2

Code seems to skip the while loop:

int i,j;
i= floor((Lx-23.61)/0.1);
j=0; 
while(Nh - modSED[i][j] > 0.0){
    j++;
}
if(j>0 && modSED[i][j]-Nh > Nh-modSED[i][j-1]){
    fileNH=modSED[i][j-1];
}else{
    fileNH=modSED[i][j];
}

It's more or less a crude linear search through an array of doubles (the i-index is preset by another part of the code and shouldn't be a problem). The code seems to misbehave when I look at GDB:

Breakpoint 1, mag (filter=4, Lx=23.930108812418158, z=0.57071772467724535, Nh=0.011911981460606383) at infopt.c:45
45      while(Nh-modSED[i][j]>0.0){
(gdb) print Nh-modSED[i][j]
$1 = 0.001911981460606383
(gdb) n
48      if(j>0 && modSED[i][j]-Nh > Nh-modSED[i][j-1]){
(gdb) 

and it has just skipped the j++ segment, even though the while loop should evaluate to true.

Thanks, Josh

jroz
  • 103
  • 7
  • 1
    Do you have optimisations turned on (`-O`)? If so, disable that and try again. Optimisations confuse debuggers. – Greg Hewgill Jul 24 '12 at 04:53
  • You might want to also typecast i into an int because the floor function returns a double not an integer and arrays cannot be indexed with doubles – Alex Jul 24 '12 at 04:54
  • my cflags are CFLAGS =-g3 -std=c99 -Wall -I$(IDIR) in the makefile, so no optimizations. tried typecasting and it didn't change the behavior. – jroz Jul 24 '12 at 04:57
  • 5
    I wouldn't necessarily trust what gdb thinks about any of the values of your variables. Have you tried simply printing out some values in your code and seeing what you get? "When in doubt, print more out." – Greg Hewgill Jul 24 '12 at 05:10
  • 1
    Did the program *actually* skip the body of the `while` loop, or did the debugger just skip showing you the execution of the loop iterations (in other words, is `j` still `0` after the `next` command or was it incremented at all)? The `step` command might be your friend here if GDB is getting confused by the code generated by the compiler for the loop. – Michael Burr Jul 24 '12 at 06:04
  • Put a log statement inside the loop and another just after it. Frankly, I wouldn't completely trust gdb for all sorts of reasons. Many is the time I have been confused by what its telling me only to find out that I had changed the source code but forgotten to compile it. – JeremyP Jul 24 '12 at 08:38
  • 1
    Even with the step command, j never seemed to be incremented, but then after the while loop, the program would return a value that would suggest that j hadn't been zero (even though GDB still said it was 0). The actual problem was that the external 2D array was declared with the wrong dimensions, so either the program, gdb, or both were confused. Fixing the dimensions of the declaration fixed the problem. Since GDB seemed to give the wrong output though, I was getting hung up on the wrong part of the code. I still don't understand why gdb failed to show j as being incremented. – jroz Jul 24 '12 at 16:27

2 Answers2

1

Seems like a error creeping up due to floating point comparisons. It is well known that floating point comparisons are not very safe. Refer to these for more info:

The second link has a very detailed explanation on Floating Point Operations

Community
  • 1
  • 1
darnir
  • 4,870
  • 4
  • 32
  • 47
  • I was wondering about something like this, but 0.002 isn't so horribly small, and gdb even says that the while loop evaluates to true...and then skips it (I didn't include it above, but I told gdb to "print Nh-modSED[i][j]>0" and it gives "1" as the result. – jroz Jul 24 '12 at 05:01
  • This particular problem is pretty unlikely to be floating point related. Floating point comparison `> 0.0` is very well defined. – Greg Hewgill Jul 24 '12 at 09:09
1

The external 2D array modSED was declared with the wrong dimensions (different from the c file in which it was initialized), so either the program, gdb, or both were confused. Fixing the dimensions of the declaration fixed the problem. (Here the problem refers to the larger issue that I wasn't getting the correct value returned from modSED.) Since GDB seemed to give the wrong output, though, I was getting hung up on the wrong part of the code.

Perhaps this in turn led to GDB seeming to defy logic and skip the while loop? (Running the program now, GDB has no trouble incrementing j and showing that it has done so.)

jroz
  • 103
  • 7