- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have been liberally using non-signalling nans as a debug aid. I can use these anywhere an initialization expression is allowed. But having no signalling limits the usefulness of this method.
I tried to make use of the new option Qinit:snan but that is only applicable to local scalars which are a small subset of the cases I need.
I create a parameter for my initialization like this:
real(DP), parameter :: aNaN = 0.0D0 / 0.0D0.
and declare arrays within derived types like this:
type Bar real(DP) :: vec(3) = [aNaN, aNaN, aNaN] end type
So why not change the declaration of aNaN to a signalling version I thought. But having done so it still does not trap.
This code demonstrates that even if my aNaN parameter has the same bit pattern as Qinit:snan it fails to trap assignment. I also tried the portable IEEE_VALUE function to get a signalling nan it it did not trap either.
program TestSignalingNaN implicit none integer, parameter :: DP = 8 real(DP), parameter :: aNaN = z'7FFFBADDADBADDAD' !Value from Qinit:snan real(DP), parameter :: bNaN = z'7FFC000000000000' !IEEE_VALUE(1.0_DP, IEEE_SIGNALING_NAN) real(DP), save :: cNaN real(DP) :: a a = aNaN a = bNaN a = cNaN !Only this assignment gets trapped end program
The setting for fpe: flag does not appear to make any difference.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The assignment of cNaN gets trapped in default 32 bit debug configuration (windows) but the 64 bit version traps nothing !
Using compiler Intel(R) Visual Fortran Compiler XE 15.0.3.208
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My observation is that you get the trap when the value is used, not on assignment. But I can't completely explain the behavior and will talk to the developers about it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Slightly confused, was there something missing in the code snipped? In a = cNaN, cNan is uninitialised or is it initialised to nan by compiler option....?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
cNaN would have been set to a SNaN by the compiler when /Qinit:snan was used.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How about this?
program p use, intrinsic :: iso_fortran_env, only : r8 => real64 use, intrinsic :: ieee_arithmetic, only : ieee_value, ieee_signaling_nan, ieee_quiet_nan use, intrinsic :: ieee_exceptions , only : ieee_invalid, ieee_set_halting_mode implicit none real(r8) :: a real(r8) :: b call ieee_set_halting_mode(ieee_invalid, .true.) a = ieee_value(real(0.0, kind(r8)), ieee_quiet_nan) print *, " a = ", a b = ieee_value(real(0.0, kind(r8)), ieee_signaling_nan) print *, " b = ", b stop end program p
a = NaN forrtl: error (65): floating invalid Image PC Routine Line Source p64.exe 000000013FA21932 MAIN__ 17 p.f90 p64.exe 000000013FAC6B7E Unknown Unknown Unknown p64.exe 000000013FAC764C Unknown Unknown Unknown p64.exe 000000013FAC778E Unknown Unknown Unknown kernel32.dll 0000000076BA59BD Unknown Unknown Unknown ntdll.dll 00000000772BA551 Unknown Unknown Unknown
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FortranFan , although your excellent code has the advantage of standard conformance it is not code that could be used to provide default initialization. For that we need a constant parameter.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Copy operations may be difficult to trap. This is because, the copy could use general purpose registers, or it could use integer SIMD instructions.
If you want to assure a trap in debug mode, force an expression on the variable.
#define test_snan(x) (x + 0.0_D)
If the compiler optimizes that out, then make the test a call to an external function that does not get inlined, and is not optimized.
I agree with your desire to have /Qinit:snan, at least in Debug build, use instructions that will cause a trap on simple assignments. This could be done with the add literal 0.0. as part of the assignment.
Jim Dempsey

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page