2013-03-15 3 views
4
#include<stdio.h> 
#define CUBE(x) (x*x*x) 

int main() 
{ 
int a, b=3; 
a = CUBE(++b); 
printf("%d, %d\n", a, b); 
return 0; 
} 

이 코드는 a=150b=6의 값을 반환합니다. 이것을 설명해주십시오.이 C 프로그램의 출력을 설명 하시겠습니까?

나는 그것이 그렇게 논리를 설명해주십시오 a의 값이 a=4*5*6=120로 계산됩니다하지만 컴파일러에 따라 사실이 아니다 실행할 때 생각이 ....

에는 논리가 없다
+0

5*5*6에서 표현식을 평가? gcc 4.2.1을 사용하면 결과가 표시됩니다. a = 120, b = 6 –

+1

@Magnus : 어떤 결과라도 가능합니다. 'a = 120, b = 6' 또는'감자 '를 얻을 수 있습니다. 정의되지 않은 동작입니다. –

답변

9

, 그것은 정의되지 않은 동작 때문이다

++b * ++b * ++b; 

은 인터리빙 순서 포인트없이 b을 3 회 변경하고 읽습니다.

보너스 : CUBE(1+2)을 시도하면 이상한 행동이 보일 것입니다. 그것은 특히, 추적 다운하는 버그를 미묘하고 매우 어려운 발생할 수 호출 할 때 : Luchian 고르 당신이 매크로가 끔찍한 것을주의해야 (이 이상한 행동을 관찰 이유를 설명하는) 말 이외에

5

문은 부작용 (예 : ++b)이 있기 때문에 문이 여러 번 실행됩니다.

이로부터 3 일을 배워야한다 :

  1. 결코 참조 매크로 인수 번 매크로보다. 이 규칙에는 예외가 있지만 절대적이라고 생각하는 것이 좋습니다.

  2. 가능한 경우 부작용이있는 문을 매크로를 호출하지 마십시오.

  3. 시도해보십시오. 가능한 경우 기능적 매크로 인을 피하십시오. 인라인 함수를 대신 사용하십시오.

2

undefined behavior 동일한 변수를 시퀀스에서 한 번 이상 변경해야합니다. 그리고 이러한 이유 때문에 코드에 대해 다른 컴파일러를 사용하면 결과가 달라집니다.

나는 동일한 결과를 얻고있다. 내 컴파일러는 a = 150 and b = 6이다.

a = ++b * ++b * ++b; 

그리고 b

gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) 

매크로 표현 a = CUBE(++b); 한 확대는 full expression.의 끝나기 전에 다시 한 번 다음 변경됩니다.

그러나 내 컴파일러가 낮은 수준 (이 비슷한 방식으로 컴파일러 일 수 있으며 동일한 기술로 시도 할 수 있음)이 표현식을 어떻게 변환합니까? 이를 위해 -S 옵션을 사용하여 소스 C를 컴파일하고 어셈블리 코드를 얻었다.

gcc x.c -S 

파일은 x.s입니다.나는이 검사에 내 대답

movq %rsp, %rbp 
.cfi_def_cfa_register 6 
subq $16, %rsp 
movl $3, -8(%rbp) // b = 3 

addl $1, -8(%rbp) // b = 4 
addl $1, -8(%rbp) // b = 5 

movl -8(%rbp), %eax // eax = b 
imull -8(%rbp), %eax // 5*5 = 25 

addl $1, -8(%rbp) // 6 `b` become 6 and 

imull -8(%rbp), %eax // 6 * 25 = 150 
movl %eax, -4(%rbp) // 150 assign to `a` become 150 

movl $.LC0, %eax  // printf function stuff... 
movl -8(%rbp), %edx 
movl -4(%rbp), %ecx 
movl %ecx, %esi 
movq %rax, %rdi 

를 추가하고 왜 150 출력을 수행하는 방법을 알고 싶어하기 때문에 나는 부분 유용한 ASM 코드를 표시하고

(댓글를 읽기), 이잖아 어셈블리 코드 나는 a = 5 * 5 * 6과 같은 표현을 이해할 수 있으므로 a150이되고 세 번째 증분이 b이된다. 6.

다른 컴파일러는 다른 결과를 생성하지만 난 생각하지만, 150 택시는이 b=3에 대한 순서와 사용하는 어떤 컴파일러

관련 문제