2012-03-31 9 views
2

현재 문자를 다음 문자로 설정해야합니다. 예를 들면 :왜 * foo ++ = * ++ foo가 정의되지 않았습니까?

while(*foo) { 
if(baa(*foo)) *foo++ = *++foo; 
    foo++; 
} 

그러나 나는 다음과 같은 오류를 얻을 :

error: operation on ‘foo’ may be undefined [-Werror=sequence-point] 
cc1: all warnings being treated as errors 

사람이 이유를 설명 할 수 있습니까? 그건 유효한 C 구문이 아닌가요?

+1

먼저 검색하십시오 ("C 시퀀스 포인트"가 좋은 시작이 될 것입니다). 오류 메시지는 모두 (또는 대부분) : 잘 정의 된 방식으로 동일한 시퀀스 포인트에서 객체를 두 번 수정할 수 없다고 말합니다. 이것은 C가 정의되는 방식입니다 (또는 경우에 따라 잘 정의되지 않음). –

+0

나는 C 프로그래머가 아니지만 사물의 모습에서 보면 오류가 말하는 것과 정확히 같아서'* foo'는 값이 없습니다. 즉'undefined '입니다. 존재하지 않는 것에 무언가를 추가 할 수 없습니다. –

+0

루프 안에서 3 번 증가하고 있습니다. 물론 이것이 당신이 원하는 것입니까? –

답변

4

의이 표현에 대해 자세히 살펴 보자 *(foo++)이 (후위 ++이 단항 *보다 더 높은 우선 순위를 가지고 있습니다)로

*foo++ = *++foo 

*foo++는 평가를; foo의 현재 값을 취하여 참조를 취소하고 foo을 부작용으로 처리하십시오. *++foo*(++foo)으로 평가됩니다 (단항 *++은 모두 동일한 우선 순위를 갖기 때문에 왼쪽에서 오른쪽으로 적용됩니다). foo + 1의 값을 취한 후 결과의 참조를 취소 한 다음 foo을 부작용으로 다시 전진하십시오. 그런 다음 두 번째 표현식의 결과를 첫 번째 표현식에 할당합니다.

문제는 모든 부작용이 적용된 (할당, 후행 증가 및 사전 증가) 정확한 순서는 입니다. 지정되지 않음; 컴파일러는 자유롭게 해당 작업을 적절하게 재정렬 할 수 있습니다. 이 때문에 형식이 x++ = ++x 인 경우 다른 컴파일러 또는 다른 컴파일러 설정을 사용하는 동일한 컴파일러 또는 주변 코드를 기반으로하는 결과가 달라집니다.

언어 표준은 명시 적으로 정의되지 않은 동작이 너무 그 컴파일러 구현을 시도하고 "옳은 일을"할 어떤 요구 사항, 상황 그들이 맞는 볼 어떤 방법을 처리 할 무료 (무엇이든 "옳은 일로서이 부른다 " 아마도). GCC는 분명히이 경우에 진단을 내리지 만 반드시 할 필요는 없습니다. 한 가지는 모든 사례가 이렇게 쉽게 감지 할 수있는 것은 아닙니다. 상상해보십시오

void bar (int *a, int *b) 
{ 
    *a++ = *++b; 
} 

이 문제가 있습니까? ab이 동일한 것을 가리키고 있지만 호출자가 별도의 번역 단위 인 경우에만 컴파일 타임에이를 알 수있는 방법이 없습니다.

+1

이 예제에서는 int가 포인터가 아닌 값이 증가하도록 수정해야한다고 생각합니다. +1 좋은 설명. – ams

6

사이에 시퀀스 포인트가없고 할당의 양쪽에서 foo이 증가하고 있습니다. 그것은 허용되지 않습니다. 시퀀스 포인트간에 한 번만 값을 수정할 수 있습니다.

관련 문제