Это выглядит гарантированно стандартом, мы можем начать с раздела [expr.static.cast] p4 , который говорит:
Выражение e может быть явно преобразовано в тип T, если существует неявная последовательность преобразования из e в T ...
последовательность неявного преобразования описана в [over.best.ics] , и мы имеем следующее:
Правильно сформированная неявная последовательность преобразования является одной из следующих форм:
- (3.1) стандартная последовательность преобразования,
...
и стандартная последовательность преобразования указана в [over.ics.scs] , которая гласит:
[Примечание: как описано в [conv], стандартной последовательностью преобразования является либо преобразование идентичности само по себе (то есть без преобразования), либо оно состоит из одного-трех преобразований из других четырех категорий.
Если в последовательности есть два или более преобразований, преобразования применяются в каноническом порядке: преобразование Lvalue, повышение или преобразование, корректировка квалификации.
- конец примечания]
и у нас есть случай продвижения с плавающей запятой, который мы здесь рассмотрели в [conv.fpprom] p1 , который гласит:
Значение типа float может быть преобразовано в значение типа double.
Значение не изменяется.
Переход в другую сторону double в float будет преобразованием, которое рассматривается в [conv # double] p1 :
Значение типа с плавающей точкой может быть преобразовано в значение другого типа с плавающей точкой.
Если исходное значение может быть точно представлено в типе назначения, результатом преобразования будет именно это представление.
Если исходное значение находится между двумя смежными целевыми значениями, результатом преобразования является определенный реализацией выбор любого из этих значений. В противном случае поведение не определено.
Этот случай зависит от того, может ли источник быть точно представлен адресатом, что не гарантируется.
Вопрос о делении с плавающей точкой на ноль сложен и описан в моем ответе на Поведение деления с плавающей точкой на ноль .