Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28337 Discussions

issue with DATA statements and /Qinit for debugging

New Contributor I

I have run into an issue in one of our large programs where a DATA statement is used to initialize the values within array slices of a 2-D array, but leaving some slices uninitialized. While I understand that one cannot use a data statement to initialize the whole array to some value and then another data statement for assigning specific values for certain elements of the array, I am a bit surprised that the /Qinit:snan /Qinit:arrays compiler switches do not set elements that were 'untouched' to signal NaN. The latter is what I had hoped for (and it would have allowed me to catch an error in the code). The current behavior left me with the false believe that I would be able to catch such issues.

Here is a simple example:


program Test_data_statement

implicit none

integer :: i
real,dimension(3,3) :: rtab
real,dimension(3,1) :: rlist

data rtab / 6 * -777.7 /                !first array value initialization with data statement; note that only 6 out of 9 array entries are initialized
data rtab(1:3,2) / 0.21, 0.0, 0.23 /    !second attempted data initialization of array slice (not conforming with Fortran standard)
!data rtab(1:3,3) / 0.31, 0.0, 0.33 /   !this array slice initialization via data statement would be valid (since slice not initialized above).

write(*,*) 'rtab:'
do i = 1,3
    write(*,'(3(F9.2, 1X))') rtab(:,i)
end do

write(*,*) ''
write(*,*) 'rlist:'
write(*,'(3(F9.2, 1X))') rlist(:,1)

end program Test_data_statement

!Intel(R) Visual Fortran Compiler version issues a warning message for line 9:  
!warning #6956: In this DATA statement, there are more variables than values assigned to the variables.   [RTAB]

! -777.70   -777.70   -777.70
! -777.70   -777.70   -777.70
!    0.00      0.00      0.00       !Q: why are these values not 'NaN' when using /Qinit:snan /Qinit:arrays command line switches?
!     NaN       NaN       NaN    

!gfortran (gcc version 9.3.0) issues an error for line 9:
!Error: DATA statement at (1) has more variables than values



The code on line 10 shows an example of what was done in our original program at first, leading to unintended consequences. It would be useful if the compiler would issue an error or at least a warning about the repeated use of a DATA statement involving the same array elements. A warning is only stated that not all elements were initialized (for line 9).

Using the command line options /Qinit:snan /Qinit:arrays, I would have expected that the third line in the output for rtab would show NaN and not 0.0, similar to the output for rlist. Am I wrong about this expectation or is the compiler not supposed to honor the /Qinit:snan /Qinit:arrays flags in the context of DATA use?

full command line from VS: 
/nologo /debug:full /Od /standard-semantics /warn:all /debug-parameters:all /Qinit:snan /Qinit:arrays /module:"x64\Debug\\" /object:"x64\Debug\\" /Fd"x64\Debug\vc160.pdb" /traceback /check:bounds /check:shape /check:uninit /libs:dll /threads /dbglibs /c

Labels (2)
0 Kudos
4 Replies
Black Belt

The compiler believes that you initialized the array, so it doesn't generate code to fill in just the elements you skipped over. 

0 Kudos
Honored Contributor II

As you probably know the /Qinit options are a dirty fix to old/bad coding practices of the past. I appreciate the task of fixing can be too big a task but at lease aim to fix segments of code that you work on then the task gets smaller over time. 

0 Kudos
Honored Contributor II

You are looking for a convenience from your compiler vendor to overcome code deficiencies, so you can petition your vendor to see if they appreciate your need.

For your actual code, given its size. legacy, etc., your choice may be limited but if some refactoring is  possible and your compiler support allows, you can consider using IEEE facilities in the standard in conjunction with an indexing scheme.  See a simple example below:

   use, intrinsic :: ieee_arithmetic, only : ieee_value, ieee_quiet_nan

   integer :: i
   real :: x(9)
   integer, parameter :: nelem = 6
   integer, parameter :: idx(size(x)) = [ [( 1, i=1,nelem )], [( 0, i=nelem+1,size(x) )] ]  

   data x(1:nelem) / nelem * 42.0 /  ! Aaray section initialization

   where ( idx == 0 ) x = ieee_value( x, ieee_quiet_nan )
   print *, "x = ", x


Here's the program response using 2 different compilers with standard option:

C:\Temp>ifort /standard-semantics p.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version Build 20200623
Copyright (C) 1985-2020 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.26.28806.0
Copyright (C) Microsoft Corporation.  All rights reserved.


 x =  42.00000 42.00000 42.00000 42.00000 42.00000
 42.00000 NaN NaN NaN

C:\Temp>x86_64-w64-mingw32-gfortran.exe -std=f2018 p.f90 -o p.exe

 x =    42.0000000       42.0000000       42.0000000       42.0000000       42.0000000       42.0000000                  NaN              NaN              NaN



By the way, can you confirm you are aware the use of DATA statement causes "implied SAVE" attribute and which can affect subprogram semantics, hinder multithreading, parallelization etc.?


0 Kudos
New Contributor I

Thanks to all for your replies. 
I am aware of the implied SAVE with use of DATA statements. I also would not recommend using /Qinit:zero unless for good reasons in legacy code.  My issue was simply that the use of /Qinit:snan in this case did not help (and essentially prevented) trapping of missed/erroneous initialization statements in the code and relying on /Qinit:snan in terms of detecting missed initializations is therefore not recommended in the case of arrays initialized by DATA, which may be good to know for others too. In cases of other scalar variables and arrays, it has been a useful feature offered by the Intel compiler.

I will replace such DATA statements from older code sections by other / better ways of data initialization. In the use case of our code, DATA was most often used to initialize, within a module declaration part, large tables of array values that are constants. In such a case, a better approach is to replace those initializations with PARAMETER statements for the arrays. 

0 Kudos