[clang] [C23] Add INFINITY and NAN macros to <float.h> (PR #96659)
Aaron Ballman via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 27 05:24:46 PDT 2024
AaronBallman wrote:
I was thinking about this more last night. The standard says:
> The macro
> `INFINITY`
> is defined if and only if the implementation supports an infinity for the type float. It expands to a
> constant expression of type float representing positive or unsigned infinity.
Some interesting things to note:
* "if and only if" is clear that there are conditions under which `INFINITY` will not be defined.
* "an infinity" means some plausible, correct infinity value; because we `#pragma float_control(precise, on)`, there is a way in which to re-enable infinities for a block of code even if `-ffinite-math-only` is passed on the command line. That makes it defensible to always define `INFINITY`. However...
* "expands to a constant expression of type float representing positive or unsigned infinity" still prevents us from having a valid definition of the macro when infinity is disabled; we cannot make a valid constant expression because constant expressions are prohibited from overflowing, and because true infinity is considered representable but has properties that mean it doesn't overflow when used with mathematical operators. e.g., `INFINITY + 1.0f` is a valid constant expression only when true infinity is supported.
* You might think "but that's fine, we can add special handling for infinity to our constant expression interpreter", except there's a requirement for constant expressions that `The semantic rules for the evaluation of a constant expression are the same as for nonconstant expressions.`. It would also mean that `fpclassify` (etc) will classify such a value as an infinity at constant expression time, but not at runtime.
* We could also argue that `-ffinite-math-only` is a language dialect and so we could say "aha, none of the standard's rules apply!", but I think that's leaning on a technicality rather than helping users to write correct code. In general, we want language dialects to track as closely to the standard as they can because that's what makes the language dialect approachable for users.
I think that not defining `INFINITY` when in finite-math-only mode is the better option for the largest number of our users. People who want to play fast math games can call `__builtin_inf()` directly, but I think the fact that `INFINITY` won't actually behave like the standard expects it to behave and the standard asks us not to define it in that case is a compelling reason to not define it. I think that's the best user experience for people who aren't fast math aficionados (which is basically the majority of users, IMO).
WDYT?
https://github.com/llvm/llvm-project/pull/96659
More information about the cfe-commits
mailing list