2011-02-07 4 views
3

이 제로를 통해 루프 :`x--> 0`은 정의되지 않은 동작이 아니며`x = x -`는? 모두가 아시다시피

while (x-- > 0) { /* also known as x --> 0 */ 
    printf("x = %d\n", x); 
} 

그러나 x = x--undefined behaviour을 얻을 수 있습니다.


두 예제가 내가 생각하지 x--의 일부 '반환'값을해야합니다. x-- > 0이 정의되었지만 x = x--은 어떻게 될 수 있습니까?

+4

공식적인 이유 외에도'x = x -; '를 쓰면 이해가 안되기를 바랍니다. 'x -;'라고 쓰거나'x = x -; '의 두 번째'-'를'1' ... –

+0

@R로 대체하십시오. 나는 'x => 0'이'x = x -'처럼 정의되지 않은 이유는 무엇인가? –

+2

공식적인 관점에서,'x'는 한 번만 수정되기 때문에. 상식적인 견지에서 볼 때, 이것은'--' 연산자의 전체적인 포인트이기 때문에 수정하고 lvalue하고 오래된 값을 산출합니다. 비린내 같은 일은 일어나지 않습니다. –

답변

19

x = x--에서 중재 시퀀스 포인트없이 x의 값을 두 번 수정하고 있기 때문에. 따라서 작업 순서는 정의되지 않습니다. x-- > 0에서 x의 값은 한 번 수정되며, x--을 계산 한 결과는 감소하기 전에 x의 값이 될 것임이 명확하게 정의됩니다.

+0

아, 그래서'x -'는'x - 1'로 평가되지만'x = x -'의 순서는 정의되지 않았습니까? –

+0

@ 라덱 S : 응? 'x -'는'x '를 전혀 반환하지 않습니다. 'x -'는'x'의 원래 값 *을 반환합니다. 첫째, 원래 값은 * 감소 전의 값입니다 (여기서 "후"는?). 둘째, 'x'가 아닙니다. 'x'의 원래 값 *입니다. 변수의 * 변수 *와 * 값 * 사이의 차이점을 이해하시기 바랍니다. – AnT

+2

@Radek S :'x = x -'의 아무 것도 정의되어 있지 않습니다. 언어는'x = x -'가 정의되지 않았다고 말합니다. 즉, 무언가의 "질서"뿐만 아니라 모든 것이 정의되지 않은 것을 의미합니다. – AnT

7

"x-의 일부 '반환'가치가 필요하다는 생각이 들었는지 모르겠다." 첫째, 당신이 의미하는 바가 정확히 분명하지 않습니다. 둘째로, 당신이 무엇을 의미하는지에 관계없이 이것은 x = x--에서 정의되지 않은 행동의 근원과 관련이없는 것처럼 보입니다.

x = x--은 중재 시퀀스 포인트없이 x을 두 번 수정하려고하므로 정의되지 않은 동작이 발생합니다. 어떤 "반환 값"에 대해서도 "필요"가 없습니다.

x = x--의 근본적인 문제는 정의되지 않은 순서로 정의되지 않은 순간에 발생하는 두 가지 부작용이 있다는 것입니다. 하나의 부작용이 할당 연산자에 의해 발생합니다. 또 다른 부작용은 접미어 -- 연산자에 의해 소개됩니다. 두 부작용은 동일한 변수 x을 수정하려고 시도하며 일반적으로 서로 모순됩니다. 이것이 그러한 경우의 행동이 정의되지 않은 것으로 선언 된 이유입니다. x의 원래 값 5 있었다면

는 예를 들어, 다음 식은 동시에 4 (감소의 부작용) 및 5 (할당 부작용) 모두가 될 x 필요하다. 말할 것도없이,은 현재 45이 될 수 없습니다.

UB가 발생하는 데 이와 같은 직접적인 모순 (예 : 4 vs 5)이 필요하지 않지만. 끼어 들지 않는 시퀀스 포인트없이 동일한 변수에 두 개의 부작용이 발생할 때마다 이러한 부작용이 변수 일치에 넣으려는 값이더라도 그 동작은 정의되지 않습니다.

+1

예를 들어'(x = 1) + (x = 1)'은 정의되지 않은 동작을 호출합니다. –

3

이것을 이해하려면 시퀀스 포인트에 대한 기본적인 이해가 필요합니다. 이 링크를 참조하십시오 : 어떤 순서 지점이없는 = 운영자를 들어 http://en.wikipedia.org/wiki/Sequence_point

를, 그래서 다시 x에 할당되기 전에 x의 값이 수정 될 것이라는 보장은 없습니다.

while 루프에서 조건을 검사 할 때 은 이 한 번만 수정되기 때문에 x--이 평가되고 관계 연산자 평가에서 값이 사용되므로 정의되지 않은 동작이 발생하지 않습니다.

1

나는 https://stackoverflow.com/a/21671069/258418을 읽을 것을 제안합니다. =sequence point이 아니며 컴파일러가 링크 된 답변에서 시퀀스 포인트로 분리되지 않는 한 조작을 인터리브 할 수 있습니다. 즉, 다음 두 시퀀스가 ​​유효하다는 것을 알 수 있습니다.

일반적으로 동일한 변수에 두 표현식을 두 번 할당하지 마십시오 (예 : pre/post ++/-에 의한 수정 포함).

관련 문제