2014-01-29 2 views
4

for 루프 내의 변수에 값을 할당하는 것과 관련하여 질문이 있습니다. 필자는 Microsoft에서 말한 것처럼 아직 할당되지 않은 변수를 읽을 수있는 가능성이있을 때 컴파일러에서이 오류 메시지를 표시합니다.무제한 변수의 사용 - for 루프

이 오류는 컴파일러에서 특정 코드가 할당되지 않은 경우에도 할당되지 않은 변수를 사용할 수있는 구성을 발견했을 때 생성됩니다.

내 코드는 다음과 같습니다

나는이 특정 시나리오에 i 할당 받게됩니다에도 불구하고, 컴파일러가 있음을 의미하는 for 문 내부의 실제 상태를 확인하지 않는 가정
static void Main(string[] args) 
{ 
    int i; 

    for (int j = 0; j <= 5; j++) 
    { 
     i = j; 
    } 

    Console.WriteLine(i.ToString()); 

    Console.ReadLine(); 
} 

치료하겠습니까

for (int j = 0; j <= -1; j++) 

그냥 똑같습니까?

답변

4

현재 사건은 사소한 것처럼 보이지만 루프는 다음과 같습니다 경우 어떻게 : 그것을 반환 할 수처럼

int i; 

for (int j = 0; j <= GetUpperLimit(); j++) 
{ 
    i = j; 
} 

GetUpperLimit 5를 반환 할 수 -3 i가 할당되지 얻을 않습니다. 런타임 동안 응용 프로그램의 상태에 전적으로 의존 할 수 있으며 컴파일러는 사전에이를 분명히 알 수 없습니다. 간단한 int i = 0으로 문제가 해결됩니다.

조건이 거짓 const 또는 리터럴 인 경우 for 루프가 최적화됩니다.데모 사용 LINQPad : IL을 생성

int i; 

for (int j = 0; j <= -1; j++) 
{ 
    i = j; 
} 

대신 식의 오류 문자와 지금

IL_0001: ldc.i4.0  
IL_0002: stloc.1  // j 
IL_0003: br.s  IL_000D 
IL_0005: nop   
IL_0006: ldloc.1  // j 
IL_0007: stloc.0  // i 
IL_0008: nop   
IL_0009: ldloc.1  // j 
IL_000A: ldc.i4.1  
IL_000B: add   
IL_000C: stloc.1  // j 
IL_000D: ldloc.1  // j 
IL_000E: ldc.i4.m1 
IL_000F: cgt   
IL_0011: ldc.i4.0  
IL_0012: ceq   
IL_0014: stloc.2  // CS$4$0000 
IL_0015: ldloc.2  // CS$4$0000 
IL_0016: brtrue.s IL_0005 

: IL을 생성

int i; 

for (int j = 0; false; j++) 
{ 
    i = j; 
} 

: 마찬가지로

IL_0001: ldc.i4.0  
IL_0002: stloc.1  // j 
IL_0003: br.s  IL_0005 
IL_0005: ldc.i4.0  
IL_0006: stloc.2  // CS$4$0000 

, if(false) { ... } 최적화되어 있지만 bool b = false; if(b) { ... }은 아닙니다. 이것은 모두 정적 분석의 결과입니다.

+0

당신의 예에서 컴파일러는 미리 이것을 알 수 없을 것입니다. 그러나 제 생각에는 그렇게 할 것입니다. 그러므로 약간의 혼란. – Kapol

+0

@Kapol 답변을 올렸습니다. – Vache

13

for 루프 내에서 변수 i에 값을 할당 했으므로 컴파일러가 어떤 값을 할당 할 것인지, 따라서 오류가 있는지를보기에 충분히 똑똑하지 않습니다.

간단한 해결책은 변수에 일부 기본값을 할당하는 것입니다.

int i = 0; 

루프 변수가 컨트롤 for 루프를 입력하지만, 컴파일러가 결정할 수 있다고 표시 값으로부터 않는다. 기능 부재의 실행 코드 내의 특정 위치에 5.3 Definite assignment

오류의 이유 때문에 언어 사양이다

,

을하는 변수 명확히 경우 할당이라고 컴파일러는 정적 흐름 분석에 의해 을 증명할 수 있습니다. 변수가 자동으로 초기화되었거나 하나 이상의 할당 대상이되었습니다.

평가 조건은 정적 플로우가 아니며 런타임에 결정됩니다. 따라서 컴파일러에서는 i에 값을 할당 할 것인지 여부를 결정할 수 없습니다.

+1

컴파일러는 변수가 초기화되었는지 여부를 평가할 때 중첩 된 범위를 고려하지 않기 때문에 약간 더 일반적인 문제입니다. – Magus

+0

@Magus : 나는 받아 들일 수있는 대답으로 코멘트를 표시 할 수 있다고 생각하지 않지만, 가능하다면 - 나는 그렇게 할 것이다. 나는 그것이 일반적으로 어떻게 보이는지 알고 싶었다. – Kapol

+1

@Magus, 중첩 범위가 무엇을 의미합니까, 나는 그것이 조건 때문에라고 생각합니다. 변수 할당이'{{{i = 10; }}}', for 루프 대신에 에러가 발생하지 않습니다. 컴파일러가 조건 – Habib