2011-10-23 3 views
3

가능한 중복 :단항 : C#에서의 단항 동작에 따라 변화 이유는 C/C++

int x = 2; 
int y = x + 4 * ++x; 
// what is y??? 
:

Undefined, unspecified and implementation-defined behavior
Undefined Behavior and Sequence Points
Pre & post increment operator behavior in C, C++, Java, & C#

나는이 코드 조각을

내가 컴파일에서 테스트 C/C++ 내가 얻을 것이다 :

// C/C++ 
y is 15 

그러나 C#을를 통해

나는

// C# 
y is 14 

이유를 얻을 수 있습니다?


IL의 일부이다

locals init ([0] int32 x, 
[1] int32 y) 
IL_0000: nop 
IL_0001: ldc.i4.2 
IL_0002: stloc.0 
IL_0003: ldloc.0 
IL_0004: ldc.i4.4 
IL_0005: ldloc.0 
IL_0006: ldc.i4.1 
IL_0007: add 
IL_0008: dup 
IL_0009: stloc.0 
IL_000a: mul 
IL_000b: add 
IL_000c: stloc.1 
IL_000d: ldloca.s y 
C 및 C에서
+5

"때문에." 나에게 완벽하게 좋은 대답 인 것 같아. –

+0

@David는 이것을 다루는 속임수 링크를 추가했습니다. :) –

+0

고마워요, @ R.MartinhoFernandes, 저는 의견을 삭제하고 그 질문이 중복임을 동의합니다. –

답변

5
int y = x + 4 * ++x; 

++, 각각의 피연산자의 평가 순서는 x 또는 4*++x 하나 전에 평가 될 수 있음을 의미 지정되지 다른 하나. 피연산자의 평가 순서는 지정되지 않으므로 전체 표현식의 결과는 지정되지 않습니다. x4*++x으로 평가되면

다음 y 같이 계산한다 : 4*++xx 먼저 평가되는 경우 C에서 다음

int y = x + 4 * ++x; //original 

int y = x + (4*3) //evaluate 4 * ++x first 
     = 3 + 12 //evaluate x then (x is incremented) 
     = 15; 

,

int y = x + 4 * ++x; //original 

int y = 2 + 4 * ++x //evaluate x first 
     = 2 + (4 * 3) //evaluate 4 *++x then 
     = 14; 

마찬가지로, 피연산자해야 왼쪽에서 오른쪽으로 평가되므로 항상 14로 결과를주는 첫 번째 동작을 얻습니다.

+2

같은 표현식에서'x'를 읽고 수정하고 있기 때문에 정의되지 않은 동작이 아니며 두 시퀀스를 구분하는 시퀀스 포인트가 없으므로? – jalf

+0

지정되지 않은 UB이 경우에 @@jalf가 언급 한 것 때문에 – Praetorian

+0

@jalf : 중간에 시퀀스 포인트없이 UB를 두 번 이상 수정하지 않습니까? – Nawaz

2

사실, C++에서는 표현식의 평가 순서가 항상 지정되지 않으므로 정의되지 않은 동작을 얻습니다. 따라서 x를 처음 사용하면 이전 값이나 새 값을 읽는지 여부가 명확하지 않습니다. 두 가지 모두 가능하며 실제로 어떤 일이 일어날 지 정의되지 않는다고 명시되어 있기 때문에 실제로는 아무 것도 가능하지 않습니다.

안전한 언어로 C#은 이러한 상황을 허용 할 수 없으므로 평가 순서를보다 엄격하게 정의합니다.

+1

평가 순서는 * 불특정 *입니다. * undefined *라면 유용한 C++ 프로그램을 작성할 수 없습니다. –

+0

이 세부 사항이 수정되었습니다. 그러나 주요 문제는 동일한 변수에 대한 순차적 읽기 및 쓰기가 정의되지 않은 동작이라는 점입니다. 불특정 평가 순서가 바로 이것의 원인입니다. –

+0

@ R.MartinhoFernandes : 평가 순서는 지정되지 않았지만 여기에 표시된 코드는 아직 정의되지 않았습니다. :) – jalf