2015-01-26 4 views
3

선생님이이 코드를 제공하고 31,40을 반환하지만 이유를 파악할 수 없습니다. 그것이 무엇을 반환하는지에 대한 이유는 무엇입니까? f(ptr--)ptr 불특정 (그리고 더 specificaly ptr--ptr 사이 평가 순서 반면포인터 배열의 증가 및 감소

f(f(ptr--), ptr) 

:

void main() { 
    int *ptr; 
    int arr[5] = { 10, 20, 30, 40, 50 }; 
    ptr = &arr[3]; 
    cout << ++*ptr-- << ", " << *ptr; 
} 
+8

마지막'* ptr '과 첫 번째'ptr -'사이에는 순서 지점이 없으므로 UB입니다. – Jarod42

+5

'void main()'은'int main()'이어야합니다; C++을 가르치려는 사람은 그것을 알아야합니다. 귀하의 제목에 "포인터 배열"이 언급되어 있지만 프로그램에 "포인터 배열"이없고 배열이 있고 포인터가 있습니다 –

+3

@ Jarod42 :'<<'는 오버로드되어 있으며 내장 함수가 아니라 함수 호출입니다. 연산자는 잘 정의 된 동작을하기에 충분한 시퀀스 포인트를 제공한다고 생각하지만 재 작성해야하는 엉뚱한 코드입니다 –

답변

5
cout << ++*ptr-- << ", " << *ptr; 

문제가 감소 될 수있다

operator <<(cout.operator <<(++*ptr--), ", ").operator <<(*ptr); 

인).

주어진 코드에 대해 정의되지 않은 동작이 발생했습니다.

+1

'operator << (cout.operator << (++ * ptr--), ",") .operator << (* ptr);'입니다. 첫 번째와 세 번째는 회원입니다. 두 번째는 비회원입니다. –

+0

@ T.C .: 고침, 고마워요. (대답을 변경하지 않더라도) – Jarod42

+2

@KennyOstrom 아니요, 정의되지 않았습니다. –

3

은 C++ 표준 상태

섹션 1.9/15 intro.execution]는 : 언급 된 경우를 제외하고, 각각의 통신 사업자의 피연산자 개별 식 표현식의 평가는 unsequenced이다. (...) 동일한 스칼라 객체의 다른 부작용 또는 동일한 스칼라 객체의 값을 사용하는 값 ​​계산과 비교하여 스칼라 객체의 부작용이 정렬되지 않은 경우 동작은 정의되지 않습니다.

++*ptr--*ptr는 같은 객체를 사용하여 동일한 표현의 unsequenced 하위 표현식은 다음과 같습니다 아무것도 왼쪽에서 오른쪽으로 그들이 평가하는 것을 보장하지 않습니다. 따라서 표준에 따르면 정의되지 않은 동작이 발생합니다. 결과는 컴파일러가 먼저 *ptr을 평가 한 다음 ++*ptr--을 평가하는 것으로 나타납니다.

편집 :++*ptr--++(*ptr--))입니다. 여기에서 연산자 ++의 피연산자는 ptr의 객체를 사용하며 그 위에는 --이 부작용을 나타냅니다. 따라서 이것은 정의되지 않은 동작입니다. 귀하의 경우, 컴파일러는 먼저 *ptr--을 평가하여 40과 a가 감소한 ptr을 평가 한 후 역 참조 감소 포인터 (즉, 30을 1 씩 증가 시킴)에 ++을 적용합니다.