View previous topic :: View next topic |
Author |
Message |
anand3162
Joined: 17 Oct 2014 Posts: 26
|
Posted: Fri Oct 17, 2014 6:46 pm Post subject: Debug compile and fast compile |
|
|
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. |
|
Back to top |
|
 |
mecej4
Joined: 31 Oct 2006 Posts: 1899
|
Posted: Fri Oct 17, 2014 6:51 pm Post subject: |
|
|
Quote: | 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. |
|
Back to top |
|
 |
anand3162
Joined: 17 Oct 2014 Posts: 26
|
Posted: Fri Oct 17, 2014 7:13 pm Post subject: |
|
|
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? |
|
Back to top |
|
 |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Fri Oct 17, 2014 9:31 pm Post subject: Re: |
|
|
anand3162 wrote: |
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. _________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
 |
anand3162
Joined: 17 Oct 2014 Posts: 26
|
Posted: Fri Oct 17, 2014 9:39 pm Post subject: |
|
|
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? |
|
Back to top |
|
 |
DanRRight
Joined: 10 Mar 2008 Posts: 2923 Location: South Pole, Antarctica
|
Posted: Fri Oct 17, 2014 10:14 pm Post subject: |
|
|
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
Last edited by DanRRight on Sat Oct 18, 2014 12:16 am; edited 1 time in total |
|
Back to top |
|
 |
mecej4
Joined: 31 Oct 2006 Posts: 1899
|
Posted: Fri Oct 17, 2014 10:30 pm Post subject: |
|
|
Quote: | 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.
Code: | 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 previous line, where the uninitialized value is used. If you compile with /zero, when run the program will probably crash with a mysterious access violation.
Last edited by mecej4 on Sat Oct 18, 2014 2:37 am; edited 3 times in total |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Fri Oct 17, 2014 10:53 pm Post subject: |
|
|
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:
Code: |
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
|
|
|
Back to top |
|
 |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Sat Oct 18, 2014 11:13 am Post subject: Re: |
|
|
anand3162 wrote: | 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.
anand3162 wrote: |
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.
anand3162 wrote: |
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. _________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
 |
anand3162
Joined: 17 Oct 2014 Posts: 26
|
Posted: Mon Oct 20, 2014 3:38 pm Post subject: |
|
|
Thanks you David, John, mecej4, and Dan.
All your inputs have helped me clarify this issue of mine. I really appreciate your time. |
|
Back to top |
|
 |
|