On 22/06/2019 23:21, Marc Glisse wrote: > We should care about the C standard, and do whatever makes sense for C++ > without expecting the C++ standard to tell us exactly what that is. We > can check what visual studio and intel do, but we don't have to follow them. > > -frounding-math is supposed to be equivalent to "#pragma stdc fenv_access on" > covering the whole program.
i think there are 4 settings that make sense: (i think function level granularity is ok for this, iso c has block scope granularity, gcc has translation unit level granularity.) (1) except flags + only caller observes it. i.e. exception flags raised during the execution of the function matter, but only the caller observes the flags by checking them. (2) rounding mode + only caller changes it. i.e. rounding mode may not be the default during the execution of the function, but only the caller may change the rounding mode. (3) except flags + anything may observe/unset it. i.e. exception flags raised during the execution of the function matter, and any call or inline asm may observe or unset them (unless the compiler can prove otherwise). (4) rounding mode + anything may change it. i.e. rounding mode may not be the default or change during the execution of a function, and any call or inline asm may change it. i think -frounding-math implements (2) fairly reliably, and #pragma stdc fenv_access on requires (3) and (4). -ftrapping-math was never clear, but it should probably do (1) or (5) := (3)+"exceptions may trap". so iso c has 2 levels: fenv access on/off, where "on" means that essentially everything has to be compiled with (3) and (4) (even functions that don't do anything with fenv). this is not very practical: most extern calls don't modify the fenv so fp operations can be reordered around them, (1) and (2) are more relaxed about this, however that model needs fp barriers around the few calls that actually does fenv access. to me (1) + (2) + builtins for fp barriers seems more useful than iso c (3) + (4), but iso c is worth implementing too, since that's the standard. so ideally there would be multiple flags/function attributes and builtin barriers to make fenv access usable in practice. (however not many things care about fenv access so i don't know if that amount of work is justifiable). > 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 the first one, I am not sure. I guess you should only write > that in "fenv_access off" regions and I wouldn't mind a compile error. iso c specifies rules for const expressions: http://port70.net/~nsz/c/c11/n1570.html#F.8.4 static/thread storage duration is evaluated with default rounding mode and no exceptions are signaled. other initialization is evaluated at runtime. (i.e. rounding-mode dependent result and exception flags are observable).