Почему преобразование большого двойного в uint16_t с оптимизацией в gcc и clang дает разные ответы - PullRequest
0 голосов
/ 01 декабря 2018

Приведенный ниже код дает другой результат на gcc, когда оптимизация включена.Без оптимизации gcc выдает тот же результат, что и clang.

#include <cfloat>
#include <cstdint>

double big_dbl() { return DBL_MAX; }

int main() {
    return static_cast<std::uint16_t>(big_dbl());
}

Вывод ассемблера для -O0 показывает, что и gcc, и clang вызывают empty_dbl и используют cvttsd2si для преобразования с плавающей запятой-> intс последующим преобразованием в 16-битное значение без знака и выдачей 0.Повышение уровня оптимизации до -01 оптимизирует вызов empty_dbl в обоих компиляторах, но clang по-прежнему выдает 0 в результате приведения, тогда как gcc дает 65535. Результаты можно увидеть с помощью проводника компилятора .

Это ошибка в оптимизаторе gcc или неопределенное поведение, так что оптимизатор может делать то, что ему нравится?

Это укусило нас в последнее время, и в некотором смысле, к счастью, как показалоСценарий, в котором big_dbl использовался неправильно, и мы исправили код правильно, но я хотел бы понять разницу с gcc.

1 Ответ

0 голосов
/ 01 декабря 2018

Цитата из текущего проекта стандарта:

Значение типа с плавающей запятой может быть преобразовано в значение типа целого числа.Преобразование усекается;то есть дробная часть отбрасывается. Поведение не определено, если усеченное значение не может быть представлено в типе назначения.

Таким образом, реализации могут делать все что угодно для вашего случая, поскольку поведение не определено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...