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).

Reply via email to