C++ of the Day #2 - Sequence points.

Question

역시 C++ 뉴스그룹에 올라온 질문 하나 ((comp.lang.c++.moderated:Sequence points.))
int c = 0;
cout << c++ << c;
질문을 요약하면...
  1. 위 문장의 결과는 undefined라고 한다.
  2. 하지만 이 경우는 다음과 같이 번역되지 않는가?
    cout.operator<<(c++).operator<<(c);
    
  3. 인자를 evaluation 한 후에 함수가 호출되므로 이 사이에는 반드시 [[http://en.wikipedia.org/wiki/Sequence_point|sequence point]]가 있어야 하지 않나?
  4. 따라서 출력은 항상 01 이 되어야 하지 않나?


Answer

함수가 리턴하고 그 리턴된 객체의 함수가 호출되는 사이에는 sequence point가 존재합니다. 하지만 이는 함수 호출 사이의 순서를 보장해줄 뿐입니다. 위의 문장에서 두 인자의 evaluation 순서는 보장되지 않습니다. 설명을 쉽게 하기 위해 위의 문장을 다음 네개로 나누어보겠습니다.
  1. cout.operator<<
  2. c++
  3. *((1번의 operator<<가 리턴한 객체)).operator<<
  4. c
여기서 함수 사이의 sequence point에 의해 1번이 3번보다 먼저 호출된다는 것이 보장됩니다. 하지만 인자의 evaluation인 2번, 4번의 순서는 보장되지 않습니다. 위에서 질문자는 이 경우 2 -> 1 -> 4 -> 3번순으로 실행된다고 예상했으나 실제로는 4 -> 2 -> 1 -> 3번순으로 실행되어도 컴파일러로서는 표준을 위반하지 않은 것이 됩니다. 물론 이런 순서로 실행되면 출력은 00 이 됩니다. 여기서 중요한 점은 이런 순서의 차이점은 단지 출력만을 얘기하는 것이 아니라 인자가 evaluation되면서 생기는 모든 side effect에 대한 것이라는 점입니다. 간단한 해결책은 다음과 같이 두줄로 풀어쓰는 것입니다.
int c = 0;
cout << c++;
cout << c;
이 경우엔 문장의 끝(;)이 sequence point가 됩니다.

Comments

Popular Posts