Detecting uninitialized arrays

社会主义新天地 提交于 2019-12-02 01:44:45

If you are on Linux, you could use valgrind for this task. If you issue

valgrind --track-origins=yes ./a.out

you will get a lot of output ;-) The first warning actually points towards the uninitialized variable:

==4426== Memcheck, a memory error detector
==4426== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==4426== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==4426== Command: ./a.out
==4426== 
==4426== Conditional jump or move depends on uninitialised value(s)
==4426==    at 0x4F29774: ??? (in /usr/lib64/libgfortran.so.3.0.0)
==4426==    by 0x4F2B2DE: ??? (in /usr/lib64/libgfortran.so.3.0.0)
==4426==    by 0x4F1F126: _gfortran_transfer_array (in /usr/lib64/libgfortran.so.3.0.0)
==4426==    by 0x40098B: MAIN__ (test.F90:34)
==4426==    by 0x400A75: main (test.F90:28)
==4426==  Uninitialised value was created by a stack allocation
==4426==    at 0x4008CD: MAIN__ (test.F90:27)

To better analyze the output, I prefer to have one statement per line, so I changed the last lines of your program to

    call set_int_array  ( a )
    print *, a(:)
    call set_real_array ( r )
    print *, r(:)

Then, test.F90:34 points towards

    print *, a(:)

Later on, you will find the following output which points towards the second use of an uninitialized variable:

==4426== Conditional jump or move depends on uninitialised value(s)
==4426==    at 0x4F27BC1: ??? (in /usr/lib64/libgfortran.so.3.0.0)
==4426==    by 0x4F2A6E4: ??? (in /usr/lib64/libgfortran.so.3.0.0)
==4426==    by 0x4F2B29E: ??? (in /usr/lib64/libgfortran.so.3.0.0)
==4426==    by 0x4F1F126: _gfortran_transfer_array (in /usr/lib64/libgfortran.so.3.0.0)
==4426==    by 0x400A44: MAIN__ (test.F90:36)
==4426==    by 0x400A75: main (test.F90:28)
==4426==  Uninitialised value was created by a stack allocation
==4426==    at 0x4008CD: MAIN__ (test.F90:27)

Note that you will need to compile your code with debug options to get the line numbers. With valgrind it is also beneficial to correct one error after the other, starting from the first. This is because undefined behavior might cause subsequent errors/warnings that are gone once you fix the cause of the problem.

If detecting such error is important to your work, you might want to invest in the NAG compiler which can report such problem at runtime. For example, if I save your original code in 'test.f90' and compile it:

nagfor test.f90 -C=undefined -o test.exe

At runtime I get the following:

Runtime Error: test.f90, line 11: Reference to undefined variable A(K)
Program terminated by fatal error
Aborted (core dumped)

If I uncomment and fix the first error, the second one is reported as well:

11 12 13 14 15
Runtime Error: test.f90, line 21: Reference to undefined variable R(K)
Program terminated by fatal error
Aborted (core dumped)

Compilers do not normally perform this kind of check because it can be expensive. There are some limitations as well. More information is available at http://www.nag.co.uk/nagware/np/r60_doc/nagfor.html#UNDEF

Note that the answer is from a NAG person. The above link gives information on limitations on the use of '-C=undefined' flag, which is not directly related to this question but may be useful.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!