Silverfrost Forums

Welcome to our forums

Debug compile and fast compile

17 Oct 2014 5:46 #14874

Here is a question regarding a Fortran compile error.

I have a program with a nested if statement as follows,

If (conditionA) then If (conditionB) then Executable lines of code Executable lines of code Executable lines of code Endif Endif

When I do a fast compile of the above section of code, I have no problems and the code executes smoothly. However, when I run the code within the debugger, then the program crashes at conditionA for an array indexing of bounds issue.

My question is why does the fast compile not crash? Why is it that only the debug compile crashes? If the array indexing is out of bounds for the debug compile, it will be out of bounds for fast compile also.

17 Oct 2014 5:51 #14875

If the array indexing is out of bounds for the debug compile, it will be out of bounds for fast compile also.

Not necessarily. For instance, if an undefined integer variable is used as an index into an array, one cannot predict whether or not an out of bounds reference occurs.

It would be better to post sample code than to talk about hypotheses.

17 Oct 2014 6:13 #14876

For instance a sample code could be

do k = 1, numberofinputs If (inputisnumber) then numindex = numindex+1 Input(numindex) = Numvalue endif enddo

if (Input(numindex) .eq. 1) then executable lines executable lines endif


numindex is declared as an integer.

Input is a 1 dimensional array of length 50, goes from Input (1) to Input (50).

If inputisnumber is false, numindex remains 0 throughout.

Therefore, Input(0) returns array index out of bounds

This index out of bounds happens only under debug compile. Why is it so?

17 Oct 2014 8:31 #14877

Quoted from anand3162

If inputisnumber is false, numindex remains 0 throughout.

Why do you think it is zero?

If you don't define a value, then it is undefined.

If you reference a value that is undefined, your program isn't standard conforming (i.e. you have made a programming error).

In such cases, a 'Fortran processor' (the compiler and run time system) can do anything at all. It looks like your debug compile shows you there is a bug and your optimized compile does not.

17 Oct 2014 8:39 #14878

David,

I do not think it is zero. I can see it is zero, when I look at the program in the debugger.

numindex is declared but not assigned a value. It stays at its default value of 0. But the array that uses numindex as its index will then be Input(0) but Input exists from 1-50 only.

Are you suggesting that this is a programming error?

I still do not understand why debug compile shows this as a bug and the optimized compile does not. For something as straightforward as an array index why does optimized compile miss it?

Is there something I can do so that such errors will be trapped out even with optimized compile?

17 Oct 2014 9:14 (Edited: 17 Oct 2014 11:16) #14880

Zeroise/initialuse all manually. The default initial state formally is not a zero but any trash in memory could be in given location. Compiler usually takes care and zeroises arrays and variables for you (not always) but when in debug mode it is not making you excuses looking at all possible faults of programmer. I use compile option /zeroise

17 Oct 2014 9:30 (Edited: 18 Oct 2014 1:37) #14881

numindex is declared but not assigned a value. It stays at its default value of 0.

There are no default values unless you provide default initialization in the declaration of the variable(s) concerned, or use a 'save my skin' option such as /zero.

DavidB is an experienced and expert programmer. His advice merits careful consideration.

Optimization and bug checking do not go well together. Any time spent doing runtime checking is time that, in bug-free code, would have been used profitably in computing good results.

The Fortran language has certain rules. If you knowingly break the rules, and conclude that 'I saw no evil, therefore there is no evil', you may be in for a very unpleasant surprise some day. Bugs can remain dormant for a long time. Some bugs even disappear when you look for them (they are called Heisenbugs). Don't take things for granted, and don't generalize from your experience without a sound basis.

Here is a fleshed out version of your code to help you understand the issues.

program tstuninit
implicit none
logical :: inputisnumber = .true.
integer :: numindex,k,numberofinputs=50,input(50),numvalue=-5

do k = 1, numberofinputs 
   If (inputisnumber) then 
      numindex = numindex+1 
      Input(numindex) = Numvalue 
   endif 
enddo 

if (Input(numindex) .eq. 1) then 
  write(*,*)Input(2)
endif
end program

If you compile and run with the /check option, the program will stop at the line where *numindex *is used as a subscript in the loop. If you next compile and run with the /undef option, the program will stop at the [u:7352073a01]previous [/u:7352073a01]line, where the uninitialized value is used. If you compile with /zero, when run the program will probably crash with a mysterious access violation.

17 Oct 2014 9:53 #14882

If numindex = 0 is a valid outcome from the do loop then you should change the second part of your code to cope with that:

You should also initialise numindex = 0 before the start of the code group and also change the first part to check numindex keeps in range. Grouping these suggested changes would have:

numindex = 0

 executable lines 

do k = 1, numberofinputs 
 ?? code to assess input k
 If (inputisnumber) then 
  if (numindex < 50) then
    numindex = numindex+1 
    Input(numindex) = Numvalue 
  else
    report numindex overflow: too many numbers
  end if
 endif 
enddo 

if (numindex > 0) then
 if (Input(numindex) .eq. 1) then 
  executable lines 
  executable lines 
 endif 
else
 report no number is yet available
endif 
18 Oct 2014 10:13 #14883

Quoted from anand3162 David, I do not think it is zero. I can see it is zero, when I look at the program in the debugger.

What you see in the debugger doesn't reflect the true position though. Compile with Checkmate enabled and look at the variable again in the debugger and you will see it is undefined. In the optimised version it is probably given some random 'out of bounds' value.

Quoted from anand3162

Are you suggesting that this is a programming error?

Yes. In Fortran you cannot reference undefined variables and expect the program to give the same results on different compilers or the same compiler with different options.

Quoted from anand3162

I still do not understand why debug compile shows this as a bug and the optimized compile does not. For something as straightforward as an array index why does optimized compile miss it?

Is there something I can do so that such errors will be trapped out even with optimized compile?

You can turn on bounds check. However, with this example, there is a small possibilty that the random index will be in range and the bug will be missed.

What you should do is compile and run with /CHECKMATE then when it works recompile with optimize enabled. This includes bounds checking and undefined variable checking and is all you really need.

If you want to 'see' the bug in your optimize code, you can use 'drmemory' (google it) to discover all the out of bounds reads and writes your code does.

20 Oct 2014 2:38 #14902

Thanks you David, John, mecej4, and Dan.

All your inputs have helped me clarify this issue of mine. I really appreciate your time.

Please login to reply.