Submitter:Fred Tydeman
Submission Date: 2019-07-28
Document: WG14 N2406
Reference Documents: CFP emails 1247, 1249, 1250, 1253, 1316, 1340

Summary

The standard appears to be ambiguous as to what is an acceptable signaling NaN initializer.

7.12#7 has:

If a signaling NaN macro is used for initializing an object of the same type that has static or thread-local storage duration, the object is initialized with a signaling NaN value.

Does "is used for initializing" include being in any expression that is used as an initializer, or just being the initializer? The former would include not only -SNANF but also 1.0 + SNAN.

Is static float f = -SNANF; {required / allowed / prohibited} to be a signaling NaN?

IEC 60559 rules evaluate 1.0 + SNAN to a quiet NaN and -SNAN to a signaling NaN.

Since unary minus does not trigger an SNAN, it seems that -SNAN should be accepted where ever SNAN is allowed.

Since -SNAN raises no floating-point exceptions, what about +SNAN?

Is +SNAN a copy operation?

Possible Technical Corrigendum:

Change 7.12#7 from

If a signaling NaN macro is used for initializing an object of the same type that has static or thread-local storage duration, the object is initialized with a signaling NaN value.

to

If an optional unary + or - operator followed by a signaling NaN macro is used as the initializer for initializing an object of the same type that has static or thread-local storage duration, the object is initialized with a signaling NaN value.

Change Annex F.3#1 Operation binding table: 'copy' from

    copy             memcpy, memmove,
to
    copy             memcpy, memmove, +(x)

Change Annex F.3#4 from

The unary - operator raises no floating-point exceptions, even if the operand is a signaling NaN.

to

The unary + and - operator operators raise no floating-point exceptions, even if the operand is a signaling NaN.

Existing practice

clang appears to allow any expression with an SNAN macro as being an SNAN. gcc appears to only allow SNAN, +SNAN, -SNAN as being an SNAN.