2016-06-23 3 views
6

다음 프로그램이 엄격한 앨리어싱 규칙을 위반합니까? VS2015, clang 또는 gcc에 의해 방출엄격한 앨리어싱 위반

#include <cstdint> 

int main() 
{ 
    double d = 0.1; 

    //std::int64_t n = *reinterpret_cast<std::int64_t*>(&d); // aliasing violation 

    //auto n{*reinterpret_cast<std::int64_t*>(&d)}; // aliasing violation 

    auto nptr{reinterpret_cast<std::int64_t*>(&d)}; 
    auto& n{*nptr}; 

    ++n; 
} 

없음 경고합니다.

답변

5

다음 프로그램이 엄격한 앨리어싱 규칙을 위반합니까?

예. std::int64_t*을 사용하여 double* (&d)을 역 참조합니다. 엄격한 앨리어싱 규칙을 위반

라인은 다음 라인을 처리하는 동안

auto& n{*nptr}; 

, 컴파일러는 반드시 당신이 nptr의 값을 설정하는 방법을 모르겠어요. double*에 대한 별명이라는 사실은 해당 행을 처리하는 동안 분명하지 않습니다.

5

예, 엄격한 앨리어싱을 위반합니다. 포인터 nptrdouble 또는 관련 유형에 대한 포인터가 아니지만 포인터 doubled에 액세스하고 있습니다.

컴파일러가 경고를 내 보내지 않는다고해서 그것이 위반 사항이 아님을 의미하지는 않습니다. 엄격한 위반은 UB (런타임 문제이므로)이므로 진단을 요구하지 않습니다.

+0

Re "엄격한 [앨리어싱] 위반은 UB입니다.", 전혀 아닙니다. 엄격한 앨리어싱은 최적화에 연결된 gcc 개념입니다. C++ 표준에는 재 해석 결과를 이식 가능한 방식으로 사용하거나 사용할 수없는 방법에 대한 규칙이 있습니다. 이 예에서는 공식적인 UB가 발생합니다. 그러나이 예제는 특정 플랫폼에서 유용 할 수 있습니다. –

+0

@ Cheersandhth.-Alf : "* C++ 표준에는 재 해석 결과를 휴대용 방식으로 어떻게 사용할 수 있는지에 대한 규칙이 있습니다." "이러한 규칙은 일반적으로"엄격한 앨리어싱 규칙 "이라고합니다. 기간은 GCC 선택권에서 올지도 모르지만, 규칙 자체는 아닙니다. 그래서 나는 당신의 요점이 무엇인지 보지 못합니다. 아니요,이 예는 모든 플랫폼에서 잘 정의 된 동작이 허용되지 않습니다. 3.10/10에서는'int64_1'에 대한 포인터를 통해'double'의 값에 * 절대 * 접근 할 수 없습니다. –

+0

C 및 C++ *이 특정 플랫폼에서 유형을 바꿀 수없는보기는 현실과 반대입니다. 그 반응은 제가 지적하려고했던 것의 아주 좋은 예입니다. 불행하게도이 뷰는 g ++을 플러그인 대체물로 사용하는 것보다 실제적으로 덜 유용하게 만듭니다. –

관련 문제