programing

++ * ptr ++는 C ++에서 정의되지 않은 동작입니까?

nasanasas 2020. 12. 30. 08:14
반응형

++ * ptr ++는 C ++에서 정의되지 않은 동작입니까?


++ * ptr ++ 평가에 대한 테스트에서 다음 질문을 받았습니다 (내가 직접 작성하고 싶지 않았습니다. 테스트에서 질문했습니다. 여전히 잘못된 코드를 알고 있습니다).

int Ar[ ] = { 6 , 3 , 8 , 10 , 4 , 6 , 7} ;
int *Ptr = Ar  ;
cout<<++*Ptr++  ;

그러나 둘 다 (++*ptr)++또는 일 수 있기 때문에 이것이 정의되지 않은 동작이라고 생각합니다 ++(*ptr++). 맞나요? 나는 문서에 너무 익숙하지 않아서 아무것도 찾을 수 없었습니다.


그러나 둘 다 (++*ptr)++또는 일 수 있기 때문에 이것이 정의되지 않은 동작이라고 생각합니다 ++(*ptr++). 맞나요?

구현 자에게 충분한 여유를주는 런타임 동작과는 달리 C ++ 구문 분석 자체는 매우 엄격하고 잘 정의 된 규칙 1을 따릅니다 . 실제로,보고 우선 순위 규칙 , ++*Ptr++실제로으로 분석됩니다 ++(*(Ptr++)).

대신이 트릭 질문은 식에 i = ++i + ++i여러 번 나타나는 값이 있고 식 자체의 부작용에 의해 수정 될 수있는와 같은 식의 정의되지 않은 동작을 암시 합니다. 이러한 식은 부작용을 시퀀싱하는 연산자가없는 한 2 , 적용되는 정확한 순간이 정의되지 않았으므로 i식의 다양한 지점에서 어떤 값 이 가정 할 것인지 정확히 정의되지 않기 때문에 불법 입니다.

표현의 모든 부작용 발현에 한 번만 표시 다른 값에서 작동으로 여전히, 아니 정의되지 않은 동작, 여기가 없습니다 :은 "내부는" ++영향을 미치는 Ptr외부 하나는 값에 의해 원래 지적에 영향을 미치는 동안 Ptr, 즉 Ar[0].

++(*(Ptr++))
     ^^^^^____increments Ptr, returning its original value
   ^^^^^^^^______dereferences the original Ptr, AKA &Ar[0]
^^^^^^^^^^^^_______ increments Ar[0]

즉, 우리의 코드베이스에서 그러한 표현을 본 적이 있다면 저자를 찾고 이것이 다시 발생하지 않도록 많은 노력을 기울일 것입니다.


  1. 때로는 매우 기괴하고 터무니없는 구현 비용이 드는 경우. 그럼에도 불구하고, 거기에 있는 구문 분석의 일부 코너 케이스를 기술 표준에서 정의되지 않은 동작의 인스턴스는, 그러나 "런타임"정의되지 않은 동작이보다 널리 크기의 그것의 주문.
  2. 이러한 규칙에 대한 간단한 요약은 여기에서 찾을 수 있습니다 . 흥미롭게도 C ++ 17에는 몇 가지 추가 보증이 추가되었습니다.

++*Ptr++;

UB를 유발하지 않으며 다음과 같이 평가됩니다. ++(*(Ptr++))

  • ptr++; /* address post incremented i.e doesn't change here itself */
  • *ptr; /* dereference same address i.e value at location where ptr earlier pointed i.e 6 */
  • ++*ptr; /* value changed where ptr pointed i.e Ar[0] becomes 7 */

포스트 증분 Ptr++은 다음과 같이 평가됩니다.

  • Ptr; /* Ptr doesn't change here itself in same expression */
  • Ptr = Ptr + 1; /* in next expression, Ptr considers the incremented one */

참조 URL : https://stackoverflow.com/questions/53874307/is-ptr-undefined-behaviour-in-c

반응형