10

이 두 기능을 고려char 배열을 다른 유형으로 캐스팅하는 것이 엄격한 앨리어싱 규칙을 위반합니까?

int f1() 
{ 
    alignas(int) char buf[sizeof(int)] = {}; 
    return *reinterpret_cast<int*>(buf); 
} 

int f2() 
{ 
    alignas(int) char buf[sizeof(int)] = {}; 
    char* ptr = buf; 
    return *reinterpret_cast<int*>(ptr); 
} 

GCC는 첫 번째는 엄격한 앨리어싱 규칙을 위반 한 것으로 경고하고있다. 그러나 두 번째는 OK입니다.

Clang은 불만없이 모두 허용합니다.

경고가 합법적입니까?

+0

예. 여기서 "객체"는'char' 또는'char's의 배열이고 glvalue는'int' 타입입니다; https://timsong-cpp.github.io/cppwp/basic.lval#8의 내용은이 사례를 다룹니다. –

답변

8

경고는 합법입니다. f2은 확인되지 않습니다 (정의되지 않은 동작 임). 경고를 유발하지 않습니다.

int f3() 
{ 
    int i = 0; 
    char *ptr = reinterpret_cast<char*>(&i); 
    return *reinterpret_cast<int*>(ptr); 
} 

완전히 법적인가 :

나는 f2이 경고를 자극하지 않는 이유가 있다는 것입니다 생각한다. 액세스하기 전에 올바른 유형으로 다시 캐스트하면 char* (또는 void*)을 "범용 포인터"로 사용할 수 있습니다. GCC가 f3에 대한 경고를 피하기 위해 명확하게주의를 기울이고 있으며, 경고 메시지는 f2입니다.

Clang은 f1 또는 f2에 대해 경고하지 않고 있지만 필수 사항은 아닙니다.

+0

표준 인용 부호가 필요합니다. –