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

Trying to catch use of uninitialized variables

ferrad
New User
1,959 Views
To return myself to a former era where I could regularly trap the use of uninitialized variables (it was in Salford...), I decided to try out the equivalent in Intel (/RTCu as per the docs).I switched it on for all files in my DLL, then ran, just to see if we had any problems. The application ran just fine without trapping anything. Being distrustful, I forced the use of an uninitialized variable and reran. But it didn't catch this. So I'm now wondering exactly how this /RTCu option is supposed to work.
My entire compilation line is:
ifort /nologo /c /iface:cvf /Z7 /Tfplacemen.for /define:INTEL9 /Qsave /Foplacemen.obj /fpconstant /real_size:64 /4Yb /RTCu /Zi /4R8
Is another option I'm using negating /RTCu?

Adrian
0 Kudos
40 Replies
ferrad
New User
900 Views

Can't get this to compile, it's upset with the # syntax. I think it needs to be !DEC$ something, but I can't get the syntax right for the array(i) #define.

Adrian

0 Kudos
Steven_L_Intel1
Employee
900 Views
Enable FPP under Preprocessor

When you get the array bounds error, bring the console window to the front - does it identify the source file and line?
0 Kudos
ferrad
New User
900 Views
Nope, it fails before then telling me a variable '' is used without being defined (see attached screen capture). Not sure which variable it's talking about.
Adrian
0 Kudos
Steven_L_Intel1
Employee
900 Views
That's a different problem. The name of the variable in the message will almost always be wrong. It worked in the initial 9.0 release but not now. It's being fixed.

I was asking about the array bounds problem where you could not see where in the source the error occurred.
0 Kudos
ferrad
New User
900 Views

No, it doesn't stop at all if I have all checking on except "Check Uninitialized Variables"

compiler options are:

/nologo /Zi /Od /fpp /fpe:0 /module:"$(INTDIR)/" /object:"$(INTDIR)/" /traceback /check:bounds /check:format /check:output_conversion /check:arg_temp_created /libs:static /dbglibs /c
Adrian
0 Kudos
Steven_L_Intel1
Employee
900 Views
Are you sure there's an error?
0 Kudos
Intel_C_Intel
Employee
900 Views
Hello,
I have been using the Intel compiler to trap various unititalized variables lately, and I have found a few tricks that may help.
1. First ensure that the Installation of IVF is good. If you have previous versions that are not entirely unistalled, please unistall everything (IVF related), and do reboot/regclean a few times.Then install the latest version. This may normaly not be required, but sometimes an old dll can do much harm.
2. Ensure that you enable the "Generate traceback information" switch in all projects.
3. Ensure that the floating point exception allow level is "Underflow generates zero, abort on IEEE exceptions".
4. Ensure that the all run time exceptions are enabled.
5. You may experiment by turning on and off the switch /Qtrapuv, read documentation for details.
6. You may experiment by turning on and off the switch /Qfpstkchk, read documentation for details.
7. In addition you may add to the command line "/check:all /warn:all /debug:full".
8. Before debugging, ensure to do a full clean and the a full rebuild of allinvolved projects.
9. When debugging starts, after pressing F5, please go to the Exceptions window and enable the exceptions you want to trap (se trap.jpg).
10. Sometimes you notice a cmd window with information about file and line number of the exception, but the debugger stops in some C++ code. Go to this Fortran file and set a conditional breakpoint to trap the condition yourself. In most cases this works very well.
We have trapped many bugs using IVF, that have been around a long time, in particular unitialized variables. In certain cases standard approaches does not catch an unitialized variable, and we have found the combining the option /check:unitialized with actively enabling the "Floating Point Underflow" trap in the Exception window (trap.jpg) may trap these variables.
I hope this helps.
Lars Petter Endresen

Message Edited by lpe@scandpower.no on 11-11-2005 04:41 PM

0 Kudos
Intel_C_Intel
Employee
900 Views
Hello again,
The option /check:unintializedmay set double precision variables to a very low number (correct me if Iam wrong) like 1.0E-307, and if these are used a "Floating Point Underflow" exception can be cathed if you have enabled this exception in the Exception window. This also works for arrays.
The /Qtrapuv option may sometimes be beneficial and sometimes not.
Best regards,
Lars Petter Endresen
0 Kudos
Steven_L_Intel1
Employee
900 Views
/check:uninitialied has no effect on values of variables. It does not rely on the data in variables. /Qtrapuv is not terribly useful right now.
0 Kudos
Intel_C_Intel
Employee
900 Views

Hello,

Why dounitialized variables havestrange values like 1.0E-307 in the debugger?

Lars Petter

0 Kudos
TimP
Honored Contributor III
900 Views
Small integers in the high order 32 bits, when read as double precision floating point, are interpreted as subnormal numbers. You could do the same with "legal" code, using equivalence or transfer().
0 Kudos
jim_dempsey
Beginner
900 Views

The Floating Point Processor (core) can be set to generate traps on certain errors. e.g. trap on divide by 0, underflow, overflow and some others. The bit patterns in the encoded numbers in addition to containing numbers have a few special case values (or value ranges). One of these values (two if you count the difference in sign bit) is given a value of Not A Number, (there is also + and - infinity, and then subnormal numbers).

When you set the compiler to trap on uninitialized variables one of the techniques employed by the compiler is to initialize the variables to Not A Number (NaN). Your code can overwrite a NaN without trapping but if one of these are read (and the FPU has been setup to trap on NaN) then a trap will occure and you receive a break into the debugger.

A second way to trap uninitialized numbers (an Intel person might correct me) is for the compiler to generate an address for the variable which is an invalid address. On first reference to the variable if the reference is a read then the invalid address trap is converted into a trap for reference of variable before initialization. Should the first access be a write then the address for the variable is modified to a valid address. One way to do this trick is to use self modifying code (which is frowned upon). A second way is to make all variables references i.e. the variable is not the address of the data, instead the variable contains the address of the data (similar to a dummy argument). Now after first reference the address of the data inside the variable can be updated without worry about using self modifying code.

Jim Dempsey

0 Kudos
jim_dempsey
Beginner
900 Views

Ferrad,

The screenshot error doesn't make sense. It would appear that lbound or ubound is failing. Which shouldn't be the case. This could be a compiler problem (another thread in this forum is talking about this subject).

For your purposes you know the proper lbound and most likely the ubound of your array that is failing. (the demo case used 1:10). Your code may be using an integer parameter for the size of the array (and from prior discussions 1 is the lbound of the array).

Replace the lbound(...) and ubound(...) with the correct bounds for your array.

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
900 Views
If you believe you have found a compiler bug, please submut a test case to Intel Premier Support. That's the way to get the issue investigated.
0 Kudos
ferrad
New User
900 Views
Yes, I have copied exactly the above bit of code, which contains the errors:
array(0) = 0.
array(11) = 11.
array(-1) = -1.
I have all the exception checking on as per the subsequent posting. But it does not stop in the debugger on these lines.
Adrian
0 Kudos
jim_dempsey
Beginner
900 Views

Ferrad,

You must interpret the code postings and adapt the code to your particular needs.

Snip of code from my prior post:

if((i .lt. lbound(was_array,dim=1)) .or. (i .gt. ubound(was_array,dim=1))) then
write(*,*) "gotcha - i=", i
#ifdef _DEBUG
iChk = lbound(was_array,dim=1)
#else
stop
#endif
endif

Interpretation:

When compiled in the Debug configuration the program will not Break and the program will not stop (the stop statement is not compiled in Debug).

Instead of breakingthe program forces the array index to 1. The intention here is (when in Debug) for you to place a Break Point at the location:

iChk = lbound(was_array,dim=1)


Or because of your prior lbound problem at your edited line:

iChk = 1

The purpose of the _DEBUG conditional compile section setting the index to 1 is that this permits you, when entering your break condition, to write down the caller information .AND. then continue running with the invalid index set to 1. Note, it is true that your program is continuing using an incorrect index. However, it is also true that should you decide to continue with the invalid index that you may also encounter a subsiqent index error, thus catching multiple bugs in one debug session. Now then, if after examining the caller of the first instance of the incorrect error, you determine it would be of no benifit to continue then simply stop the program.

Jim Dempsey

0 Kudos
ferrad
New User
900 Views
Ah, got you, my apologies. This works just fine.
Adrian
0 Kudos
jim_dempsey
Beginner
900 Views
Good, it seems like you are getting the hang of using fpp to help catch bugs. Remember to make the debugging macros selectible depending on compile variables. Your release code need not have the bugchecks (unless you want to include the bugchecks during a beta release). Let the preprocessor add and remove code sections depending on your requirements.
Did you resolve the lbound/ubound problem? These are intrinsic functions to the compiler and should work. (unless maybe your are compiling .F files vs .F90)
Jim
0 Kudos
ferrad
New User
900 Views

Yes, it works well, thanks for the help. I had theubound problem on Friday, but when I recompiled this morning, I didn't have it. Who knows, probably some weird stuff I was experimenting with on Friday, but now it's OK.

BTW putting the #define line in seems to invalidate my

!DEC$ FIXEDFORMLINESIZE: 132

directive as now it's complaining about code after column 72. Are /fpp and !DEC$ incompatible?

Adrian

0 Kudos
jim_dempsey
Beginner
822 Views

FPP and !DEC$ are not incompatible. FPP is sensitive to the fortran line length. If you set the fixed line length with !DEC$ then FPP might not know what the fixed length is. FPP must know what the line length is in order to construct continuation lines properly.

Try setting the line length via project option switches instead (as well). Or add the FPP option /e. The FPP options can be found using "fpp /help" on the command line. I think you may find using the ifort option for fixed line length more appropriate.

Jim Dempsey

0 Kudos
Reply