10

Uważają, że te dwie funkcje:Czy rzutowanie tablicy znaków na inny typ narusza zasady ścisłego wygładzania?

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 ostrzega, że ​​pierwszy narusza zasady ścisłego-aliasingu. Ale drugi jest OK.

Clang akceptuje oba bez reklamacji.

Czy ostrzeżenie jest uzasadnione?

+0

Tak. "Obiekt" to tutaj "char" lub tablica 'char's, a glvalue jest typu' int'; nic w https://timsong-cpp.github.io/cppwp/basic.lval#8 nie obejmuje tej sprawy. –

Odpowiedz

8

Ostrzeżenie jest uzasadnione. f2 nie jest OK (jest to niezdefiniowane zachowanie), po prostu nie powoduje ostrzeżenia.

Podejrzewam, że powodem, dla którego f2 nie prowokuje ostrzeżenia jest to, że:

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

Czy całkowicie prawny. Możesz użyć wartości char* (lub void*) jako "wskaźnika uniwersalnego" - pod warunkiem, że przed uzyskaniem dostępu wrócisz do odpowiedniego typu. GCC jest wyraźnie ostrożny, aby uniknąć ostrzeżenia o f3, kosztem nie ostrzeżenia o f2.

Clang nie ostrzega o ani f1 ani f2 - ale nie jest to wymagane.

+0

Wymaga standardowych ofert. –