ProgramingTip

++ x % = 10은 C ++에서 잘 정의되어 있습니까?

bestdevel 2020. 12. 29. 07:43
반응형

++ 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 에서 언급 한 내용 같이 , ++xx += 1위의 인용문으로 도어 지는와 동일합니다 . 할당은 값 전에 계산 순서가 지정됩니다. 이에 대한 ++x증분 값을 계산하기 전에.

이를 ++x %= 10수행하기 전에 할당이 수행되기 전에 확인하는 것이 어렵지 않습니다 .
부작용 증분 부작용은 부작용이 있습니다.

다른 방식으로 표현하기 위해 표준은 다음과 같은 순서를 적용합니다.

  • ++x10평가 -의 순서가 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.
[...]

관련된 모든 평가 관련 단항 연산자와 관련된 모든 평가 및 부작용은 해당 값보다 있습니다.

남은 것은 %= 10lvalue를 평가 하는 것입니다. 상수를 평가하는 것만이 동시적일 수 있으며 (해를 끼칠 수는 없음) 나머지는 엄격하게 순서가 지정됩니다.


나는 좋은 책을 인용하지 않고 대안적인 답을 제공 할 것입니다. 약간 다시 쓰면 그것이 명백한 생각하기 때문입니다.

++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 = E2E1 = E1 op E2 제외하고E1 는 동일합니다 .

또한 피연산자의 평가를 알아야 ++x하고 10결과의 계산 전에 일어날 %=표준 등에 의해 연산자

연산자의 피연산자의 값 계산은 연산자 결과의 값 계산 전에 순서가 지정됩니다.

결론:

++xlvalue를 주면 한 번만 평가되고 해당 %=작업이 수행 된 후에 만 평가됩니다 . 이것은 두 가지 수정이 모두 x시퀀싱되고 위의 표현이 잘 정의되어 있음을 의미합니다.


음, 정의됩니다 . 정의되지 않은 동작으로 :

§1.9 / 15 :
스칼라 개체에 대한 부작용이 동일한 스칼라 개체에 대한 다른 부작용이나 동일한 스칼라 개체의 값을 사용하는 값 ​​계산과 관련하여 순서가 지정되지 않은 경우 동작이 정의되지 않습니다.

여기에는 순서가 지정되지 않은 두 가지 부작용이 있습니다.

표현식 ++x %= 10;이 왼쪽에서 오른쪽으로 이동 하면 다음 과 같습니다.

  1. 값 계산 (x+1)
  2. 개체 수정 ( =,에서와 같이 x = x + 1), 예 : §1.9 / 12에 따른 부작용
  3. 동일한 스칼라 객체 ( ' ')에 대해 자체적으로 값 계산 ( ' ')과 객체 수정 부작용 ( ' ') ( ibid from 1,2 )을 모두 갖는 불확실하게 시퀀스 된 연산 ( ).%=%=x

전체 표현식의 두 하위 표현식은 서로에 대해 순서 가 지정되지 않습니다. 왼쪽에서 오른쪽으로 읽는 것으로 시작했지만, 순서불확실 하므로 §1.9 / 13에서 명시 적으로 부분 순서 지정 구제 금융이 없습니다.

두 평가 감안 B 경우, A는 하기 전에 서열화 B 다음의 실행 A를 실행한다 선행 B를 . 경우 A는 전에 서열화되지 BB는 전 서열되지 다음 B가 있다 unsequenced .

그래서 UDB.


접두사 증분 (++ x)은 모듈러스 할당 (% =)에서 가장 높은 우선 순위를 갖습니다. 진술 : ++ x % = 10; 다음과 같이 표현할 수 있습니다.

++x;
x%= 10;

참조 URL : https://stackoverflow.com/questions/27835808/is-x-10-well-defined-in-c

반응형