정의되지 않은 동작을 시작하기 전에 N4659 (C ++ 17)에 명시 적으로 나열되어 있습니다.
i = i++ + 1; // the value of i is incremented
그러나 N3337 (C ++ 11)
i = i++ + 1; // the behavior is undefined
무엇이 바뀌 었습니까?
내가 수집 할 수있는 것, [N4659 basic.exec]
명시된 경우를 제외하고, 개별 연산자의 피연산자 및 개별 표현식의 하위 표현식 평가는 순서가 없습니다. [...] 연산자의 피연산자의 값 계산은 연산자 결과의 값 계산 전에 순서화됩니다. 메모리 위치에 대한 부작용이 동일한 메모리 위치에있는 다른 부작용이나 동일한 메모리 위치에있는 객체의 값을 사용한 값 계산과 관련하여 순서가없고 잠재적으로 동시 적이 지 않은 경우에는 동작이 정의되지 않습니다.
여기서 값 은 [N4659 basic.type]에 정의되어 있습니다 .
사소 복사 가능한 유형의 값의 표현은 결정 객체 표현의 비트 세트 인 값을 값의 구현 된 집합의 하나 개의 개별 요소,
명시된 경우를 제외하고, 개별 연산자의 피연산자 및 개별 표현식의 하위 표현식 평가는 순서가 없습니다. [...] 연산자의 피연산자의 값 계산은 연산자 결과의 값 계산 전에 순서화됩니다. 스칼라 오브젝트의 부작용이 동일한 스칼라 오브젝트의 다른 부작용이나 동일한 스칼라 오브젝트의 값을 사용한 값 계산과 관련하여 순서가 지정되지 않은 경우, 동작은 정의되지 않습니다.
마찬가지로, 값은 [N3337 basic.type]에 정의되어 있습니다 .
사소하게 복사 가능한 유형의 경우, 값 표현은 구현을 정의한 값 세트의 개별 요소 인 value 를 결정하는 오브젝트 표현의 비트 세트입니다.
중요하지 않은 동시성을 언급하고 스칼라 객체 대신 메모리 위치 를 사용한다는 점을 제외하고는 동일 합니다 .
이러한 유형의 산술 유형, 열거 유형, 포인터 유형, 멤버 유형에 대한 포인터
std::nullptr_t
및 cv 규정 버전을 통칭하여 스칼라 유형이라고합니다.
예제에 영향을 미치지 않습니다.
가입일 [expr.ass N4659]
대입 연산자 (=)와 복합 대입 연산자는 모두 오른쪽에서 왼쪽으로 그룹화됩니다. 모두 왼쪽 피연산자로 수정 가능한 lvalue가 필요하고 왼쪽 피연산자를 참조하는 lvalue를 반환합니다. 왼쪽 피연산자가 비트 필드 인 경우 모든 결과는 비트 필드입니다. 모든 경우에, 할당은 오른쪽과 왼쪽 피연산자의 값 계산 후와 할당 식의 값 계산 전에 순서화됩니다. 오른쪽 피연산자는 왼쪽 피연산자보다 먼저 시퀀싱됩니다.
가입일 [expr.ass N3337]
대입 연산자 (=)와 복합 대입 연산자는 모두 오른쪽에서 왼쪽으로 그룹화됩니다. 모두 왼쪽 피연산자로 수정 가능한 lvalue가 필요하고 왼쪽 피연산자를 참조하는 lvalue를 반환합니다. 왼쪽 피연산자가 비트 필드 인 경우 모든 결과는 비트 필드입니다. 모든 경우에, 할당은 오른쪽과 왼쪽 피연산자의 값 계산 후와 할당 식의 값 계산 전에 순서화됩니다.
유일한 차이점은 N3337에 마지막 문장이 없다는 것입니다.
그러나 왼쪽 피연산자 i
가 id-expression 이 lvalue 인 것처럼 "다른 부작용" 이나 "같은 스칼라 객체의 값 사용 " 이 아니기 때문에 마지막 문장은 중요하지 않습니다 .