2011-01-08 5 views
12

다음 문을 고려하십시오. b에 저장된 값은 무엇입니까?조건부 연산자 사용

int a=1; 
int b = a+=1 ? a+=1 : 10; 

나는 4로 답을 얻는다.

+7

정의되지 않은 동작입니다. – GWW

+1

@GWW : 아니요! [....] –

+3

"아무도 어떻게 작동하는지 설명 할 수 있습니까?" >> 나는 확실히 그것을 할 수 없다. 프로그래머에게 그것을 쓴다. 그리고 그에게 다시 글을 써달라고하지 마십시오. :) – Mehrdad

답변

14

우선 순위와 관련이 있습니다. 당신이 (편의상 변경 가장 오른쪽 a+=1와) 다음 코드를 검사하는 경우 :

#include <iostream> 

int main (void) { 
    int a=1; 
    int b = a+=1 ? 7 : 10; 
    std::cout << b << std::endl; 
    return 0; 
} 

당신은 출력이 8하지 7 또는 10 것을 볼 수 있습니다.

int b = a+=1 ? 7 : 10; 

는 것으로 해석되고있다 : 문 때문이다

위해,

int b = (a += (1 ? a += 1 : 10)); 

과 : 귀하의 경우에 그 적용 지금

int b = (a += (1 ? 7 : 10)); 

, 우리는 도착 실행 유형 :

  • 가장 오른쪽의 a += 1 (이 true이므로)은 a에서 2으로 설정합니다.
  • 가장 왼쪽의 a += 2 (2은 이전 단계의 결과 임)은 a에서 4으로 설정합니다.
  • b = 4 (4은 이전 단계의 결과 임).

반드시 해당 평가 순서에 의존 할 수는 없습니다. ?에 시퀀스 포인트가 있어도 (계속하기 전에 1이 완전히 평가됩니다), 오른쪽의 a += ...과 가장 왼쪽의 a += ... 사이에는 시퀀스 포인트가 없습니다. 그것은 당신을 제공 사실 것을 4 순수한 우연의 일치

warning: operation on ‘a’ may be undefined 

것을 : 그리고 개입 시퀀스 포인트없이 두 번 하나의 변수를 수정하는 것은 gcc -Wall는 당신에게 매우 유용한 메시지를 줄 것이다 왜 정의되지 않은 동작입니다. 그냥 쉽게 당신에게 3, 65535을 제공하거나 심지어 당신에게

+0

@shreedhar : 예 코멘트를 삭제했습니다. 이 대답은 옳은 것 같습니다. –

+0

BTW g ++에서 "a '에 대한 연산이 정의되지 않았을 수 있음을 경고합니다. –

+1

@Prasoon : 왜냐하면'a + = a + = 1'은 정의되지 않았기 때문입니다. – ephemient

2

조립 분석 :-) 교훈을 가르쳐 하드 디스크를 포맷 할 수 있습니다 : 위의 코드 (는 MinGW를 사용하여) 생성

int main() 
{ 
    int a=1; 
    int b = a+=1 ? a+=1 : 10; 
    return 0; 
} 

어셈블리 코드입니다 아래에 나와 있습니다. 그 의견은 물론 내 것이다. 의견도 읽어보십시오!

call ___main  //entering into main() 
movl $1, 12(%esp) //int a = 1; means 12(%esp) represents a; 
incl 12(%esp)  //a+=1 ; a becomes 2 
movl 12(%esp), %eax //loading 'a' onto a register(eax); eax becomes 2 
addl %eax, %eax  //adding the register to itself; eax becomes 4 
movl %eax, 12(%esp) //updating 'a' with the value of eax; 'a' becomes 4 
movl 12(%esp), %eax //this step could be optimized away; anyway it loads value of 'a' onto the register(eax); eax becomes 4, in fact even earlier it was 4 too! needless step! 
movl %eax, 8(%esp) //loading the value of eax at another memory location which is 8(%esp); this location represents b; 
movl $0, %eax  //making eax zero! the return value of main()! 
leave    //now main() says, please leave me! 

12(%esp)

a의 메모리 위치를 나타내고, 그것으로부터의 거리로 4 바이트, 즉, 8(%esp)b를 나타낸다. 결국이 두 메모리 위치의 값은 4입니다.

따라서, B도 = 4. = 의한 해석되어야 방법 화합물 식 판별 C의 문법 ++이 두 코드 단편은 동일 다른 답변에 명시된 바와 같이 제

6

.

int a=1; 
int b = a+=1 ? a+=1 : 10; 

int a=1; 
int b = (a += (1 ? (a += 1) : 10)); 

조건부 표현식는 제 식 (1)의 평가 사이 및 중에서 제 중 어느 하나의 평가 순서 지점이 있지만 세 번째 표현식이 평가됩니다 (이 경우 a += 1). 두 번째 또는 세 번째 표현식을 평가 한 후에 명시적인 추가 시퀀스 포인트가 없습니다.

이것은 코드가 정의되지 않은 동작 을 갖도록 a는 개재 서열 포인트없이 b위한 이니셜 두 번 변경되는 것을 의미한다.

+0

정답입니다. Charles를 잘 잡습니다. :) +1 –