2012-02-18 5 views
0

이 코드를 실행하면 gcc에서 결과가 10이됩니다.gcc가 왜 나에게이 결과를 제공합니까?

누군가 내가 왜 저에게 10을 주는지 설명 할 수 있습니까? :)

#include <stdio.h> 

int f(int x) { 
    int y; 
    y = 2*x; 
} 

int g() { 
    int z; 
    return z; 
} 

int main() { 
    int x=5; 
    f(x); 
    printf("%d\n",g()); 
} 
+1

-Wall, IMO가 없으면 C 프로그램을 컴파일하면 안됩니다. –

답변

2

:

int g() { 
    int z; 
    return z; 
} 

이 읽기 ​​: 당신은 당신의 정수가 예약 된 메모리를 사용한 적이

int g(): 
    reserve memory for an integer, call it z. 
    return whatever is in that reserved memory. 

. 그 값은 사용하기로 결정하기 전 (또는 사용하지 않기 위해) 그 주소에 있던 값과 같습니다. 그 가치는 무엇이든 될 수 있습니다.

다른 기능에서도 똑같이합니다. 당신이하고있는 일은 초기화되지 않은 메모리를 읽는 것입니다. 자세한 내용은 google을 참조하십시오. "스택"및 "힙", 동적 메모리 및 기타 관련 항목을 참조하십시오.

+0

그것은 나를 위해 물건을 정리. 감사. :) – Gaui

6

이것은 정의되지 않은 동작입니다. 값을 설정하지 않은 변수를 참조하고 있습니다. 아마도 컴파일러가 f()의 변수에 대해 동일한 메모리 위치를 사용했기 때문에 10을 제공 할 수 있습니다. 그러나 보장 할 수는 없으며 의존해서는 안되며 호기심 이상의 것입니다.

0

g 위치가 마지막으로 설정 설명 거기에 아무것도 당신에게 X * 2 = 10

3

의 답을주는 F 기능에 의해 것을 당신의 예에서, 스택에서 초기화되지 varable를 반환합니다. 두 번째 별개의 관련이없는 경우 코드에서 정의되지 않은 동작을 나타냅니다. int으로 선언되었지만 g이 초기화되지 않은 값을 반환하기 때문에 첫 번째로 f은 아무 것도 반환하지 않습니다.

실질적으로 기능이 호출 스택에 넣어 될 방법은 원인이됩니다 로컬 yprintf 호출 g()의 반환 값으로 같은 장소에있을 (결국 값 10이있는), 그래서 당신에게 값 10을 보게됩니다. 그러나 운이 좋든 적든간에.

+0

엄밀히 말하면'f()'는 함수의 값이 사용되지 않기 때문에 정의되지 않은 동작을하지 않습니다. 그러나 분명히 문제 영역입니다. –

+0

@MichaelBurr : "void가 아닌 함수에서 값을 반환하지 않습니다"라는 모호한 생각은 이미 그 함수 반환 값을 나중에 사용하는 것이 아니라 UB입니다. 그래도 확인해야 겠어. 그리고 C는 C++과 다를 수 있습니다. –

0

z를 초기화하지 않으므로 스택에서 y와 같은 위치를 사용하기 때문입니다. 초기화하지 않으므로 이전 값이 그대로 유지됩니다. 여기

0

이것은 사람들이 최적화를 두려워하는 이유와 그들이 자신의 상사에게 컴파일러 버그를 찾는 것에 대해 자랑 할 때 완벽한 예입니다. 이 코드는 다른 사람이 암시 한 것처럼 g()에 초기화되지 않은 변수를 사용하는 것에 대한 경고를 발생시킵니다. 컴파일러 설정에 따라 스택에서 이전 값인 f(5)을 사용하고 있습니다. 다른 컴파일러 최적화 설정을 사용하면 변수가 스택에서 끝나는 방식에 영향을 미칠 수 있으므로 변경 사항을 적용 할 때 결과가 달라질 수 있습니다. 이것은 정의되지 않은 동작이므로 호출 결과와 컴파일러가 스택을 설정하는 방법을 이해하여 대개 설명하기 쉽지만 어떤 값이 될지에 대한 보장은 없습니다. 이런 이상한 행동을 해결할 때 경고가 표시되면 경고를 먼저 수정 한 다음 그 이유에 대해 질문을 시작하십시오.

관련 문제