2009-09-26 4 views
1

입니다. 다음 코드는 y를 답으로하지만 42를 y에 할당하지 않았습니다. y는 42가 될 수 있습니까?할당되지 않은 변수의 값은

#include <stdio.h> 

void doit2(void) 
{ 
    int x; 
    int y; 
    if (x == 42) 
    { 
     printf("x is the answer\n"); 
    } 
    else if (y == 42) 
    { 
     printf("y is the answer\n"); 
    } 
    else 
    { 
     printf("there is no answer\n"); 
    } 
} 

void doit1(int a) 
{ 
    int b = a; 
} 

int main(void) 
{ 
    doit1(42); 
    doit2(); 
} 
+4

"어떻게하면 * 42 * 될 수 있습니까?" –

+0

y가 무엇을 기대합니까? – recursive

+0

중복 : http://stackoverflow.com/questions/1225788/uninitialized-values-being-initialized/1225790 – GManNickG

답변

12

이것은 함수가 호출되는 방식 때문입니다. doit1이 호출되면 a (42) 인수가 호출 스택에 저장되고 b (42 개)이 바로 위에 있습니다. doit1을 종료하고 doit2을 입력하면 xy은 같은 장소에 있습니다. abdoit1입니다. 어느 쪽도 초기화되지 않았기 때문에, 그들은 그 자리에 이미있는 값을 사용합니다 - 당신의 경우에는 42입니다. 물론 최적화에 따라 이 항상이 될 수는 없지만 실제로는 좋은 방법 일 것입니다.

위키 백과에 대한 기사는 how the call stack works입니다.

10

는 스택/레지스터/임시 변수의 문제를 지적하는 몇 가지 답변이있을거야,하지만 난 당신이 최적화를 컴파일하는 경우, 아무 대답이 없음을 지적하고 있습니다. 당신이하지 최적화 할

 
$ gcc -O3 42.c -o 42 
$ ./42 
there is no answer 
$ gcc -O2 42.c -o 42 
$ ./42 
there is no answer 

또한, 대답은 컴파일러에 의존하는 것 같다 GCC에서

 
$ gcc 42.c -o 42 
$ ./42 
x is the answer 
$ tcc -run 42.c 
y is the answer 

,이 어셈블리의 최적화되지 않은 doit2 결과 :

doit2: 
     pushl %ebp 
     movl %esp, %ebp 
     subl $24, %esp 
     cmpl $42, -4(%ebp) 
     jne  .L2 
     movl $.LC0, (%esp) 
     call puts 
     jmp  .L5 
.L2: 
     cmpl $42, -8(%ebp) 
     jne  .L4 
     movl $.LC1, (%esp) 
     call puts 
     jmp  .L5 
.L4: 
     movl $.LC2, (%esp) 
     call puts 
.L5: 
     leave 
     ret 

최적화되었을 때 우리는 42와 비교조차하지 않습니다 :

doit2: 
     pushl %ebp 
     movl %esp, %ebp 
     subl $8, %esp 
     movl $.LC2, (%esp) 
     call puts 
     leave 
     ret 
1

x와 y의 값은 정의되지 않았습니다. 할당 된 위치에있을 것입니다. 귀하의 경우

는 Y 변수는 어느 a 파라미터 또는 변수가 bdoit1 방법 것과 동일한 지점에 할당된다. 이는 사용했던 컴파일러에서 사용한 특정 설정으로 발생합니다.

  • doit1 함수는 함수로 존재할 수 또는 인라인 : 다른 방식으로 구현 될 수있는 많은 것들을 있기 때문에 다른 조합은 다른 결과를 제공 할 수 있습니다.
  • doit1 함수의 매개 변수는 스택이나 레지스터로 보낼 수 있습니다.
  • doit1의 변수 b이 존재할 수도 있고 존재하지 않을 수도 있습니다. 사용 된 적이 없기 때문에 컴파일러는이 명령문을 제거 할 수 있습니다.
  • doit2에있는 xy 변수 중 하나를 스택이나 레지스터에 임의의 조합으로 할당 할 수 있습니다.
관련 문제