1

I was debugging in gdb when I came across this oddity:

(gdb) 
107                     newIterationRequired = infoAvailableUntil+1 < sqrt(input)+1 && isPrime ? TRUE : FALSE;
(gdb) 
107                     newIterationRequired = infoAvailableUntil+1 < sqrt(input)+1 && isPrime ? TRUE : FALSE;
(gdb) print infoAvailableUntil+1 < sqrt(input)+1 && isPrime ? TRUE : FALSE
$11 = FALSE
(gdb) s
108                     if (newIterationRequired)
(gdb) print newIterationRequired
$13 = TRUE

newIterationRequired's type is an enum that mimics boolean behavior from C++:

typedef enum { FALSE, TRUE } bool;

How is this possible?

Pieter
  • 31,619
  • 76
  • 167
  • 242
  • 2
    Readability suggestion: `value = condition ? TRUE : FALSE;` is the same as `value = condition;` (assuming `TRUE` is 1 and `FALSE` is 0, which they are). – Marlon Feb 25 '11 at 10:04
  • Is this running in a multithreaded environment? And are you sure that you're not skipping instructions that might change the value of `newIterationRequired`? – templatetypedef Feb 25 '11 at 10:06
  • 1
    maybe the precedence in C is different from gdb? – rene Feb 25 '11 at 10:08
  • Yes, my program uses multiple threads. However, all variables on line 107 (shown above) are local variables so I'm not forecasting any synchronization issues. I'm talking about `newIterationRequired`, `infoAvailableUntil`, `input` and `isPrime`. – Pieter Feb 25 '11 at 15:24

3 Answers3

2

I would not rely on your (or gdb's) knowledge of operator precedence in this case. Try adding a couple of parentheses to ensure that you, the compiler, and gdb are actually seeing the same thing...

newIterationRequired = ( ( infoAvailableUntil + 1 ) < ( sqrt( input ) + 1 ) ) && isPrime

Oh, and a hint: Check out <stdbool.h>...

Edit 1: Your comment says this didn't solve your problem.

Well then, pick the complex statement apart into its substatements. Store infoAvailableUntil + 1 into a temporary variable. Store sqrt( input ) + 1 into another temporary variable. Compose newIterationRequired from those temporaries. From within GDB, check if the code, you, and GDB all agree on the outcome of each intermediate step.

This is elementary debugging. Pick apart the statement that is giving you trouble, reducing its complexity, until you have found the error or can ask a very precise question.

(Personally, my next "best suspect" is that your code and gdb see a different thing when you say sqrt().)

DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • Operator precedence was my first thought as well. – user Feb 25 '11 at 10:34
  • I changed it to `newIterationRequired = ((infoAvailableUntil+1) < (sqrt(input)+1)) && isPrime` and I now use `stdbool.h`. This doesn't solve the issue however. – Pieter Feb 25 '11 at 15:19
  • Breaking down the statement into multiple variables somehow does give me the correct result: http://pastebin.com/jefYNtWM How is this possible? – Pieter Feb 25 '11 at 19:54
  • Are you sure both the C code and GDB "see" the same thing when calling `sqrt()`? In either case, `b1` shouldn't change value like that. However, you either didn't follow my link or didn't heed its advice: We still cannot reproduce your problem locally, we still have to make do with guessing because you have not *isolated* the problem. – DevSolar Feb 27 '11 at 15:39
2

GDB does not evaluate sqrt correctly as shown there: Why does gdb evaluate sqrt(3) to 0?

Community
  • 1
  • 1
Laurent G
  • 2,994
  • 1
  • 18
  • 10
1

Unless you compile with -O0, you cannot be certain that the single stepping runs one line of source code after the other. It is possible that at the time you requested the expression evaluation, all arguments have not completed, so the result is not reliable.

Another explanation, is that some argument of the expression does not exists anymore in living registers, so gdb is fooled, and does a wrong computation.

Laurent G
  • 2,994
  • 1
  • 18
  • 10
  • 1
    +1 for mentioning the relative worthlessness of step-debugging with anything else but `-O0` code. I took `-O0` for granted, but you never know... – DevSolar Feb 25 '11 at 10:49
  • I did use `-O0` as an argument for `gcc` when compiling. (Well, Eclipse's compile output says it did.) – Pieter Feb 25 '11 at 15:21
  • Can you check that every variable contains the value that you expect ? – Laurent G Feb 25 '11 at 16:14
  • I am a bit puzzled with the gdb answer that is apparently capable of evaluating sqrt(). I really wonder how it can do that ... or it does not and return 0, instead of ... say 3, in which case whole expression is reduced to `2<4`, which is true ! What's the value of *every* variable (input included) ? – Laurent G Feb 26 '11 at 20:46
  • Funny you should mention that... I have a slightly related problem with GDB evaluating sqrt(3) to 0. http://stackoverflow.com/questions/5122570/why-does-gdb-evaluate-sqrt3-to-0 – Pieter Feb 27 '11 at 10:13