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は、最初は厳しいエイリアシング規則に違反すると警告しています。しかし、2番目はOKです。

Clangは両方とも申し立てを受け付けません。

警告は正当なものですか?

+0

はい。ここの「オブジェクト」は 'char'か' char'sの配列のいずれかであり、glvalueは 'int'型です。 https://timsong-cpp.github.io/cppwp/basic.lval#8の何もこのケースをカバーしていません。 –

答えて

8

警告は正当なものです。 f2はOKではありません(未定義の動作です)、警告を発しません。

私はf2警告を誘発しないという理由があるということを疑う:

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

法的完全です。アクセス前に適切なタイプにキャストバックすれば、char*(またはvoid*)を「ユニバーサルポインタ」として使用できます。 GCCは明らかにf3に関する警告を避けるように注意していますが、約f2という警告を出さないでください。

Clangはf1またはf2のいずれかについて警告していませんが、必須ではありません。

+0

標準引用符が必要です。 –

関連する問題