2016-06-23 27 views
6

Czy następujący program narusza zasadę ścisłego aliasingu?Ścisłe naruszenie aliasingu

#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; 
} 

Brak ostrzeżenia emitowane przez VS2015, clang lub gcc.

Odpowiedz

5

Czy następujący program narusza zasadę ścisłego aliasingu?

Tak, robi. Wywołujesz dereferencję double* (&d) przy użyciu std::int64_t*.

Linia naruszające ścisłe reguły aliasingu jest:

auto& n{*nptr}; 

Podczas przetwarzania linii, kompilatory nie muszą wiedzieć, w jaki sposób ustawić wartość nptr. Fakt, że jest to alias do double*, nie jest oczywisty podczas przetwarzania tej linii.

5

Tak, to narusza ścisłe aliasing. Dostęp do obiektu d typu double, ale wskaźnik nptr, który nie jest wskaźnikiem do double lub jakiegokolwiek rodzaju z nim związany.

To, że kompilator nie emituje ostrzeżenia, nie oznacza, że ​​nie jest naruszeniem. Naruszenia o charakterze ściśle wiążącym to UB (ponieważ są one kwestią zachowania w czasie wykonywania) i dlatego nie wymagają diagnostyki.

+0

Re "Naruszenia ścisłego [aliasingu] to UB", wcale nie. Ścisłe aliasing to pojęcie gcc związane z jego optymalizacją. Zamiast tego w standardzie C++ obowiązują reguły dotyczące sposobu, w jaki wyniki reinterpretacji mogą być używane (lub nie) w przenośny sposób. W tym przykładzie powoduje to formalne UB. Ale przykład może być dobry na danej platformie. –

+0

@ Cheersandhth.-Alf: "* Standard C++ zamiast tego zawiera zasady dotyczące tego, w jaki sposób wyniki reinterpretacji mogą być używane (lub nie) w przenośny sposób." "Te reguły są ogólnie nazywane" ścisłymi regułami aliasingu "; termin może pochodzić z opcji GCC, ale same reguły nie. Więc nie rozumiem, o co ci chodzi. I nie, przykład nie może być dobrze zdefiniowanym zachowaniem na żadnej platformie. 3.10/10 nie pozwala ci * kiedykolwiek * uzyskać dostęp do wartości 'double' przez wskaźnik do' int64_1'. –

+0

Pogląd, że C i C++ * nie * potrafią pisać na konkretnych platformach, jest sprzeczny z rzeczywistością. Ta odpowiedź jest bardzo dobrym przykładem tego, co próbowałem wskazać. Niestety, ten widok sprawia, że ​​g ++ (i clang jako zamiennik wtyczki) jest mniej praktyczny niż mógł być. –