++ x % = 10은 C ++에서 잘 정의되어 있습니까?
일부 프로젝트의 코드를 탐색하는 동안 다음을 발견했습니다.
++x %= 10;
이 문장이 C ++에서 잘 정의되어 있습니까?
a[i] = i++
?
C ++ 11에 따라 1.9 Program execution /15
:
언급 된 경우를 제외하고 식별 연산자의 피연산자 및 식별 식의 하위 식에 대한 평가는 순서가 지정되지 않았습니다.
스칼라없는 경우의 부작용이 동일한 스칼라없는 경우의 부작용이 정의됩니다.
이 경우, 나는 ++x
부작용이고 x %= 10
가치 계산이라고 믿기 때문에 정의되지 않은 행동이라고 생각할 것입니다. 그러나 할당 섹션 ( 5.17 /1
)에는 다음과 같은 내용이 있습니다 (내 굵게 표시됨).
모든 경우에 할당은 오른쪽 및 왼쪽 피연산자 의 값 계산 후 할당 식의 값 계산 전에 순서가 지정됩니다.
이는 모든 순서가 지정됨을 의미합니다. 그리고 표준도 상태 (이후 5.17 /7
) x OP = y
와 동일 x = x OP y
하지만, x
한 번만 평가되고,이 판명 되어이 동등의로, 잘 정의 된 동작을 :
++x = Q % 10; // where Q is the value from ++x, not evaluated again.
질문 유일한 은 순서 가 지정 되지 않았기 때문에 할당의 어느 쪽 이 평가 되는지 입니다. 그러나 두 가지 모두 동일한 효과가 있기 때문에 중요하지 않다고 생각합니다.
++x = Q % 10; // LHS evaluated first
Q = ++x % 10; // RHS evaluated first
이것이 제가 할 표준을 읽는을 구석으로입니다. 문서를 디코딩 복잡한하는 데 상당한 경험 이 있지만 놓친 부분 이있을 수 있습니다. 모든 가이 시점에 그렇게 생각하지 않습니다. 모두 관련 섹션을 설정했습니다.
그러나 그것이 잘 정의되었는지 여부에 상관없이 괜찮은 코더 는 그런 코드를 작성 하는 관계 입니다. PDP 미니 메모리가 적의거나 저장 공간이 적은 시절이 지났기 때문에 코드를 읽을 수 있도록 작성할 때가되었습니다 .
증분하고 페이지 모듈로를 사용 x = (x + 1) % 10
하고 다음 가난한 조가 해당 코드를 읽는 것을 더 쉽게 사용할 수 있습니다.
TL; DR : x
할당 전에 증분이 보장 하도록 잘 정의 되어 있습니다.
일부 C ++ 11 표준
[intro.execution] / 15 :
언급 된 경우를 제외하고 식별 연산자의 피연산자 및 식별 식의 하위 식에 대한 평가는 순서가 지정되지 않았습니다.
그러나 [expr.ass] / 1은 다음과 같은 사항에 주목합니다.
모든 경우에 할당은 오른쪽 및 왼쪽 피연산자의 값 계산 후 및 할당 식의 값 계산 전에 순서가 지정됩니다.
따라서 첫 번째 견적에 대한 예외를 구성합니다. 더욱이, [expr.pre.incr] 1 에서 언급 한 내용 같이 , ++x
는 x += 1
위의 인용문으로 도어 지는와 동일합니다 . 할당은 값 전에 계산 순서가 지정됩니다. 이에 대한 ++x
증분 값을 계산하기 전에.
이를 ++x %= 10
수행하기 전에 할당이 수행되기 전에 확인하는 것이 어렵지 않습니다 .
부작용 증분 부작용은 부작용이 있습니다.
다른 방식으로 표현하기 위해 표준은 다음과 같은 순서를 적용합니다.
++x
및10
평가 -의 순서가 unsequenced이지만,10
여기에 관련이없는 그냥 문자 그대로 그렇게이다 .++x
평가됩니다 :- 먼저 의 값
x
이 증가합니다. - 그런 다음 값 계산이 완료되고를 참조하는 lvalue를 얻습니다
x
.
- 먼저 의 값
- 할당이 완료되었습니다. 의 업데이트 된 값은
x
모듈로 가져 오기와에10
할당x
됩니다. - 할당의 값 계산이 뒤따를 수 할당 후 명확하게 순서가 지정됩니다.
그 후
스칼라없는 경우의 부작용이 동일한 스칼라없는 경우의 부작용이 정의됩니다.
및 값 계산 부작용이 순서화 되므로 적용되지 않습니다 .
1 후위 증분을위한 [expr.post.incr]이 아닙니다!
단항 증가 연산자를 보겠습니다.
5.3.2 증가 및 감소 [expr.pre.incr]
1 접두사의 피연산자는
++
하나 추가하여 수정을하거나있는true
경우로 설정합니다bool
(이 사용은 더 이상 사용되지 않음). 피연산자는 수정 가능한 lvalue 집에 있습니다. 피연산자의 유형은 산술 유형이거나 완전히 정의 된 유형에 대한 포인터 집합니다. 결과는 업데이트 된 피연산자입니다. lvalue 이고 피연산자가 비트 필드이면 비트 필드입니다.x
이 아닌 유형 경우bool
표현식++x
은와 동일합니다x+=1
.
[...]
관련된 모든 평가 관련 단항 연산자와 관련된 모든 평가 및 부작용은 해당 값보다 있습니다.
남은 것은 %= 10
lvalue를 평가 하는 것입니다. 상수를 평가하는 것만이 동시적일 수 있으며 (해를 끼칠 수는 없음) 나머지는 엄격하게 순서가 지정됩니다.
나는 좋은 책을 인용하지 않고 대안적인 답을 제공 할 것입니다. 약간 다시 쓰면 그것이 명백한 생각하기 때문입니다.
++x %= 10; // as stated
x += 1 %= 10; // re-write the 'sugared' ++x
이 내 눈에 충분히 명확합니다. 우리가 알다시피 할당의 결과 (정말 여전히 'sugared'가 +=
감소 함) 자체가 lvalue 추가로 감소하면 즉 다음과 같다는 것은 의심의 여지가 없습니다.
(x = x+1) %= 10 // += -> =1+
x = (x+1) % 10 // assignment returns reference to incremented x
표현에서
++x %= 10;
가장 혼란스러운 부분은 x
두 시퀀스 포인트 사이에서 두 번, 접두사 ++
로 한 번, 결과 할당으로 한 번 수정 하는 것입니다. 이것은 이전 C ++에서 배운 것처럼 위의 표현식이 정의되지 않은 동작을 호출한다는 인상을줍니다.
이전 시퀀스 포인트와 다음 시퀀스 포인트 사이에서 스칼라 객체는 표현식 평가에 의해 최대 한 번 수정 된 저장된 값을 가져야합니다.
C ++ 11에서는 규칙이 다릅니다 ( 시퀀스 포인트 대신 시퀀싱 에 관한 것입니다 !).
스칼라 객체 부작용 인 경우 unsequenced 동일한 스칼라 객체 또는 객체와 동일한 스칼라 값을 이용하여 계산 값에 다른 부작용 중 하나에 대해이 동작은 정의되지 않는다.
이미 알고 있듯이 ++x
위의 표현식은 한 번만 평가되고 lvalue를 제공합니다.
C ++ 11 : 5.17
양식 표현식의 동작은 한 번만 평가 된다는 점
E1 op = E2
을E1 = E1 op E2
제외하고E1
는 동일합니다 .
또한 피연산자의 평가를 알아야 ++x
하고 10
결과의 계산 전에 일어날 %=
표준 등에 의해 연산자
연산자의 피연산자의 값 계산은 연산자 결과의 값 계산 전에 순서가 지정됩니다.
결론:
++x
lvalue를 주면 한 번만 평가되고 해당 %=
작업이 수행 된 후에 만 평가됩니다 . 이것은 두 가지 수정이 모두 x
시퀀싱되고 위의 표현이 잘 정의되어 있음을 의미합니다.
음, 정의됩니다 . 정의되지 않은 동작으로 :
§1.9 / 15 :
스칼라 개체에 대한 부작용이 동일한 스칼라 개체에 대한 다른 부작용이나 동일한 스칼라 개체의 값을 사용하는 값 계산과 관련하여 순서가 지정되지 않은 경우 동작이 정의되지 않습니다.
여기에는 순서가 지정되지 않은 두 가지 부작용이 있습니다.
표현식 ++x %= 10;
이 왼쪽에서 오른쪽으로 이동 하면 다음 과 같습니다.
- 값 계산
(x+1)
- 개체 수정 (
=
,에서와 같이x = x + 1
), 예 : §1.9 / 12에 따른 부작용 - 동일한 스칼라 객체 ( ' ')에 대해 자체적으로 값 계산 ( ' ')과 객체 수정 부작용 ( ' ') ( ibid from 1,2 )을 모두 갖는 불확실하게 시퀀스 된 연산 ( ).
%=
%
=
x
전체 표현식의 두 하위 표현식은 서로에 대해 순서 가 지정되지 않습니다. 왼쪽에서 오른쪽으로 읽는 것으로 시작했지만, 순서 가 불확실 하므로 §1.9 / 13에서 명시 적으로 부분 순서 지정 구제 금융이 없습니다.
두 평가 감안 및 B 경우, A는 하기 전에 서열화 B 다음의 실행 A를 실행한다 선행 B를 . 경우 A는 전에 서열화되지 B 및 B는 전 서열되지 다음 및 B가 있다 unsequenced .
그래서 UDB.
접두사 증분 (++ x)은 모듈러스 할당 (% =)에서 가장 높은 우선 순위를 갖습니다. 진술 : ++ x % = 10; 다음과 같이 표현할 수 있습니다.
++x;
x%= 10;
참조 URL : https://stackoverflow.com/questions/27835808/is-x-10-well-defined-in-c
'ProgramingTip' 카테고리의 다른 글
Django Rest Framework의 Serializer 클래스에 추가 인수 전달 (0) | 2020.12.29 |
---|---|
Rust의 기본 함수 인수 (0) | 2020.12.29 |
유창한 인터페이스가 데메테르의 법칙을 경유하고 있습니까? (0) | 2020.12.29 |
전화 및 Callvirt (0) | 2020.12.29 |
파일 / 디렉토리의 내용을 모니터링 하시겠습니까? (0) | 2020.12.29 |