Программа некорректна.
За [expr.const] / 4 ,
Выражение e
является выражением основной константыесли при оценке e
, следуя правилам абстрактной машины, не будет вычислено одно из следующих выражений:
[...]
операция, которая будет иметь неопределенное поведение, как указано в [intro] - [cpp] этого документа [ Примечание: включая, например, целочисленное переполнение со знаком ( [expr.prop] ), определенную арифметику указателя ( [expr.add] ), деление на ноль или определенные операции сдвига - конечная нота ];
[...]
И [expr.pre] /4 говорит:
Если во время вычисления выражения результат не определен математически или не находится в диапазоне представляемых значений для его типа, поведение не определено. [ Примечание: Обработка деления на ноль, формирования остатка с использованием делителя нуля и всех исключений с плавающей запятой варьируется в зависимости от машины и иногда настраивается библиотечной функцией.- конечная нота ]
Обратите внимание, что математически произведение двух конечных чисел никогда не является бесконечностью, поэтому произведение вызывает неопределенное поведение.Реализация может указывать такие выражения, как определено, но это все еще неопределенное поведение с точки зрения стандарта.Определение реализации не применяется ретроспективно к другим частям стандарта.Поэтому программа плохо сформирована, потому что она пытается оценить выражение, которое запускает неопределенное поведение, как константное выражение.
Интересно, что numeric_limits<double>::infinity()
равно constexpr
.Это отлично.По [numeric.limits] / infinity :
static constexpr T infinity() noexcept;
Представление положительной бесконечности, если доступно.
Имеет значение для всех специализаций, для которых has_infinity != false
,Требуется в специализациях, для которых is_iec559 != false
.
Если is_iec559 == true
, то has_infinity == true
и возвращается значение бесконечности.Если is_iec559 == false
, has_infinity
может быть true
, то в этом случае также возвращается значение бесконечности, или оно может быть false
, и в этом случае infinity()
возвращает 0
.(!)
Однако, поскольку произведение двух больших чисел не является автоматически бесконечностью (вместо этого это неопределенное поведение), противоречия нет.Передача бесконечности в порядке (значение бесконечности всегда находится в диапазоне представимых значений), но умножение двух больших чисел и допущение, что результатом является бесконечность, не является.