int32_t x = (int32_t)y;
nie jest przepełnienie i nie UB. Przepełnienie występuje wtedy, gdy operacja arytmetyczna daje wynik poza zakresem reprezentowalnych wartości. Jednak konwersja nie jest operacją arytmetyczną.
Ta sytuacja jest określana jako w przypadku implementacji. Wszystkie implementacje, o których wiem, definiują zachowanie jako nie dokonujące żadnych zmian w reprezentacji.
Uwaga: tutaj nie jest wymagana obsada. Możesz napisać int32_t x = y;
. W praktyce jest to prostsze i zawsze będzie działać. Tak wiele kodu polega na tym, że żaden sprzedawca nigdy nie zdefiniuje żadnego innego zachowania (nie, że i tak mają ku temu jakiekolwiek powody).
int32_t x = *(int32_t*)&y
nie jest UB. Nie narusza ścisłego aliasingu, ponieważ podpisana wersja typu może aliasować niepodpisaną wersję. Ten kod gwarantuje wytworzenie int32_t
z tym samym odwzorowaniem, co odpowiadający uint32_t
(tj. "Zawijanie", ponieważ te typy mają gwarantowane uzupełnienie 2).
Czy teoretycznie niemożliwe jest dokonanie konwersji bez ryzyka przepełnienia? – pingul
Co powinien zrobić, gdy wystąpi przepełnienie? Zawijanie dopełnienia dwójki (co tak naprawdę "nieokreślone zachowanie" faktycznie stanowi 99% wszystkich kompilatorów/procesorów na świecie)? – ShadowRanger
Zakładam, że 'y' jest zadeklarowane jako' uint32_t y; '(dobrze by było dodać to do pytania) –