시퀀스 포인트
Sequence point시퀀스 포인트는 컴퓨터 프로그램의 실행에서 이전 평가의 모든 부작용이 수행되고 후속 평가에서 아직 어떠한 부작용도 수행되지 않는다는 것을 보장하는 지점을 정의한다. 그것들은 종종 C와 C++와 관련하여 언급된다. 왜냐하면 그것들은 유효성을 판단하기 위한 핵심 개념이고, 유효하다면, 표현의 가능한 결과이기 때문이다. 식을 정의하고 하나의 유효한 평가 순서를 보장하기 위해 시퀀스 포인트를 더 추가하는 것이 필요할 때도 있다.
C++11에서는 용어 시퀀스 포인트의 사용이 시퀀싱으로 대체되었다. 세 가지 가능성이 있다.[1][2][3]
- 표현식의 평가는 다른 표현식의 평가보다 먼저 시퀀싱하거나, 동등하게 첫 번째 표현식의 평가 이후에 다른 표현식의 평가가 시퀀싱될 수 있다.
- 그 표현들의 평가는 제한 없이 서열화되어 있는데, 하나는 다른 것보다 먼저 서열화되지만, 이것은 불특정하다는 것을 의미한다.
- 그 표현들의 평가는 순서가 없다.
순서 없는 평가의 실행은 상태를 공유하면 치명적인 정의되지 않은 행동과 중복될 수 있다. 이러한 상황은 병렬 계산에서 발생할 수 있으며, 경주 조건을 유발할 수 있다. 그러나 이미 다음과 같은 단순한 비유동 상황에서 발생할 수 있다. (a = 1) + (b = a)
, 여기서 할당의 일부는 a
(예: 비트의 절반)은 이전에 발생할 수 있음 b = a
그리고 나머지는 그 표현에 대한 평가 후에 b
의 무의미한 중간 상태를 포함할 수 있다. a
.
모호성의 예
두 가지 기능을 고려한다. f()
그리고 g()
. C와 C++에서는 +
연산자가 시퀀스 포인트와 연결되어 있지 않으므로 표현식에서 f()+g()
어느 쪽이든 가능하다. f()
또는 g()
먼저 실행될 것이다. 쉼표 연산자가 시퀀스 포인트를 도입하므로 코드에서 f(),g()
평가 순서 정의: 첫 번째 f()
부름을 받은 다음 g()
라고 불린다.
시퀀스 포인트는 동일한 변수가 한 식 내에서 두 번 이상 수정될 때도 사용된다. 자주 사용되는 예는 C 표현식이다. i=i++
둘 다 그렇게 생각하겠지 i
그 이전의 가치와 증가. i
. 의 최종 값 i
표현 평가의 순서에 따라 증가가 과제와 함께 이전, 후 또는 인터리브될 수 있기 때문에 모호하다. 특정 언어의 정의는 가능한 행동 중 하나를 명시하거나 단순히 행동이 정의되지 않았다고 말할 수 있다. C와 C++에서 그러한 식을 평가하면 정의되지 않은 동작이 발생한다.[4] C#와 같은 다른 언어는 표현식의 결과로서 할당 및 증분 연산자의 우선순위를 정의한다. i=i++
보장된다.
C 및 C++의 시퀀스 포인트
C와[5] C++[6]에서는 다음 위치에서 시퀀스 포인트가 발생한다. (C++에서는 과부하 연산자가 함수처럼 작용하므로 과부하된 연산자는 함수 호출과 같은 방법으로 시퀀스 포인트를 도입한다.)
- &&(논리적 AND), (논리적 OR) (단락 평가의 일부)의 왼쪽과 오른쪽 피연산자에 대한 평가와 쉼표 연산자 사이의 평가. 예를 들어, 표현에서
*p++ != 0 && *q++ != 0
, 하위 시스템의 모든 부작용*p++ != 0
접속을 시도하기 전에 완료q
. - 3차 "질문 표시" 운영자의 첫 번째 피연산자와 두 번째 또는 세 번째 피연산자의 평가 사이에. 예를 들어, 표현에서
a = (*p++) ? (*p++) : 0
첫 번째 뒤에 시퀀스 포인트가 있다.*p++
즉, 두 번째 인스턴스가 실행될 때까지 이미 증가했다는 것을 의미한다. - 완전한 표현의 끝에서. 이 범주에는 표현식 문(할당 등)이 포함됨
a=b;
)), 반환문, 제어표현if
,switch
,while
또는do
-while
문장, 그리고 세 가지 표현 모두for
명세서 - 함수 호출에 함수를 입력하기 전에. 인수를 평가하는 순서는 명시되지 않지만, 이 시퀀스 포인트는 함수를 입력하기 전에 모든 부작용이 완료됨을 의미한다. 표현에서
f(i++) + g(j++) + h(k++)
,f
원래 값의 매개 변수를 사용하여 호출됨i
그렇지만i
체내에 들어오기 전에 증가한다.f
비슷하게.j
그리고k
입력하기 전에 업데이트됨g
그리고h
각각 단, 어느 순서로 되어 있는지는 명시되어 있지 않다.f()
,g()
,h()
어떤 순서로도 실행되지 않는다.i
,j
,k
증가하다 만약 의 몸이라면f
변수에 접근하다j
그리고k
둘 다, 둘 다, 둘 다, 혹은 둘 중 하나만이 증가했다는 것을 발견할 수 있을 것이다. (함수 호출f(a,b,c)
쉼표 연산자를 사용하는 것이 아니라, 다음에 대한 평가 순서a
,b
그리고c
지정되지 않음.) - 함수 반환 시 반환 값이 호출 컨텍스트에 복사된 후 (이 시퀀스 포인트는 C++ 표준에만 명시되어 있으며, C에는 암시적으로만 존재한다.)[7]
- 예를 들어, 평가 후 이니셜라이저의 끝에서
5
선언서상int a = 5;
. - 각 선언기 시퀀스의 각 선언기 사이, 예를 들어 다음 두 가지 평가 사이에
a++
에int x = a++, y = a++
.[8] (이것은 콤마 연산자의 예가 아니다.) - 입출력 형식 지정자와 관련된 각 변환 후. 예를 들어, 표현에서
printf("foo %n %d", &a, 42)
, 뒤에 시퀀스 지점이 있다.%n
평가 및 인쇄 전42
.
참조
- ^ "ISO/IEC 14882:2011". Retrieved 2012-07-04.
- ^ "A finer-grained alternative to sequence points (revised) (WG21/N2239 J16/07-0099)". Retrieved 2012-07-05.
- ^ "Order of evaluation". Retrieved 2015-10-14.
- ^ C99 규격 제6.5#2절: "이전 및 다음 시퀀스 지점 사이 물체는 표현식의 평가에 의해 최대 한 번에 저장된 값을 수정해야 한다. 더욱이, 저장될 값을 결정하기 위해서만 이전 값에 접근해야 한다."
- ^ C99 규격의 부속서 C는 시퀀스 포인트를 가정할 수 있는 상황을 열거한다.
- ^ 1998년 C++ 표준은 해당 언어의 시퀀스 포인트를 섹션 1.9, 문단 16~18에 열거한다.
- ^ C++ 표준, ISO 14882:2003, 섹션 1.9, 각주 11.
- ^ C++ 표준, ISO 14882:2003, 섹션 8.3: "선언문의 각 초기화 선언자는 마치 선언문에 있는 것처럼 별도로 분석한다."
외부 링크
- comp.lang.c에 대한 FAQ의 질문 3.8