On Sun, 23 Jun 2019, Marc Glisse wrote: > For constant expressions, I see a difference between > constexpr double third = 1. / 3.; > which really needs to be done at compile time, and > const double third = 1. / 3.; > which will try to evaluate the rhs as constexpr, but where the program is > still valid if that fails. The second one clearly should refuse to be > evaluated at compile time if we are specifying a dynamic rounding direction.
For C, initializers with static or thread storage duration always use round-to-nearest and discard exceptions (see F.8.2 and F.8.5). This is unaffected by FENV_ACCESS (but *is* affected by FENV_ROUND). > Note that C2x adds a pragma fenv_round that specifies a rounding direction for > a region of code, which seems relevant for constant expressions. That pragma > looks hard, but maybe some pieces would be nice to add. FENV_ROUND (and FENV_DEC_ROUND) shouldn't be that hard, given the optimizers avoiding code movement that doesn't respect rounding modes (though I'm only thinking of C here, not C++). You'd insert appropriate built-in function calls to save and restore the dynamic rounding modes in scopes with a constant rounding mode set, taking due care about scopes being left through goto etc., and restore the mode around calls to functions that aren't meant to be affected by the constant rounding modes - you'd also need a built-in function to indicate to make a call that is affected by the constant rounding modes (and make __builtin_tgmath do that as well), and to define all the relevant functions as macros using that built-in function in the standard library headers. Optimizations for architectures supporting rounding modes embedded in instructions could come later. Complications would include: * <float.h> constants should use hex floats to avoid being affected by the constant rounding mode (in turn, this may mean disallowing the FENV_ROUND pragma in C90 mode because of the lack of hex floats there). If they use decimal rather than hex they'd need to be very long constants to have exactly the right value in all rounding modes. * The built-in functions to change the dynamic rounding mode can't involve calling fegetround / fesetround, because those are in libm and libm is not supposed to be required unless you call a function in <math.h>, <complex.h> or <fenv.h> (simply using a language feature such as a pragma should not introduce a libm dependency). So a similar issue applies as applied with atomic compound assignment for floating-point types: every target with hardware floating point needs to have its own support for expanding those built-in functions inline, and relevant tests will FAIL (or be UNSUPPORTED through the compiler calling sorry () when the pragma is used) on targets without that support, until it is added. (And in cases where the rounding modes is TLS data in libc rather than in hardware, such as soft-float PowerPC GNU/Linux and maybe some other cases for DFP, you need new implementation-namespace interfaces there to save / restore it.) -- Joseph S. Myers jos...@codesourcery.com