j3-fortran / fortran_proposals

Proposals for the Fortran Standard Committee
175 stars 14 forks source link

Allow IEEE_VALUE in constant expressions #302

Open sblionel opened 1 year ago

sblionel commented 1 year ago

I occasionally see people trying to use IEEE_VALUE, from IEEE_ARITHMETIC, in constant expressions. The usual desire is to declare a named constant that is a NaN. Unfortunately, IEEE_VALUE is neither a transformational nor inquiry function, the classes of functions from IEEE_ARITHMETIC that are currently allowed in constant expressions. Rather, it is an elemental function.

The simplest approach would be to name IEEE_VALUE as a special case allowed in constant expressions as long as the CLASS argument is a constant. It does not depend on the value of the X argument. Can anyone think of a problem doing this? I'm not suggesting opening up all the elemental functions in IEEE_ARITHMETIC (with constant arguments) to this, though that is an obvious extension.

klausler commented 1 year ago

There's no good reason to disallow references to elemental or inquiry functions from the standard modules from constant expressions. They can all be trivially folded to constant results when presented with constant actual arguments.

(Edit: IEEE_FMA() is an exception since its result depends on the current rounding mode. It could perhaps be reclassified as an impure elemental function -- which it is, as it can set exception flags -- and then excluded from constant expressions if they admit only references to pure elemental functions from the standard modules.)

klausler commented 1 year ago

Sorry, that was a bad idea. Reclassifying IEEE_FMA to be impure would of course make it unavailable in useful contexts, and there's lots of standard intrinsics that also set exception flags. So it would be no more problematic in a constant expression than, say, COS would be.

klausler commented 1 year ago

FYI, I recently tried (again) to define a compile-time NaN parameter with newer versions of gfortran, but the ieee_value() function was rejected in initialization. So I'm still using a hex literal value taken from the runtime result to define NaN...

Be advised, the original IEEE-754 spec didn't completely define how to distinguish a quiet NaN from a signaling NaN in their binary representation, so hardware implementations differed and this usage may not be as portable as one would want it to be.