#cpp
Возьмём код: #includeint main() { unsigned char xi; unsigned char xf; int bi = -300; float bf = -300; xi = bi; xf = bf; printf("xi = %d\n", xi); printf("xf = %d\n", xf); return 0; } получаем вывод: xi = 212 xf = 0 хотя ожидалось, что unsigned char корректно переполнится и обе переменные окажутся равны 212. Что интересно, при наличии флага -O0 (без оптимизации) получается вывод как и ожидалось: xi = 212 xf = 212 при флаге -O1 и выше уже появляется отличие. По-видимому, я здесь наступил на какой-то вариант неопределённого поведения, подскажите, что именно здесь произошло? Где косяк? PS. При переполнии "вверх" на выводе получается 255, если через float пропустить, как в примере.
Ответы
Ответ 1
Переполнение при целочисленном преобразовании в беззнаковый тип подчиняется правилам Integral conversions, т.е. обрабатывается как обычно, по правилам модульной арифметики. Переполнение при плавающем преобразовании в беззнаковый тип подчиняется правилам Floating-integral conversions - т.е. это неопределенное поведение. Вот и вся разница. Нет ничего "странного" в том, что проявления неопределенного поведения меняются в зависимости от настроек компилятора.Ответ 2
Это неопределенное поведение. Тип назначения должен вмещать значение источника. см. [conv.fpint] The behavior is undefined if the truncated value cannot be represented in the destination type.
Комментариев нет:
Отправить комментарий