条件评估为true,而调试器表示它应该为false

时间:2011-02-25 10:00:43

标签: c debugging gdb

当我遇到这种奇怪的情况时,我在gdb中调试:

(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的类型是一个模仿C ++中布尔行为的枚举:

typedef enum { FALSE, TRUE } bool;

这怎么可能?

3 个答案:

答案 0 :(得分:2)

在这种情况下,我不会依赖您(或gdb)对运算符优先级的了解。尝试添加几个括号,以确保您,编译器和gdb实际上看到同样的事情......

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

哦,还有一个提示:查看<stdbool.h> ...

编辑1:您的评论说这并没有解决您的问题。

然后,将复杂的陈述分开到其子语句中。将infoAvailableUntil + 1存储到临时变量中。将sqrt( input ) + 1存储到另一个临时变量中。从那些临时代表中撰写newIterationRequired。在GDB中,检查代码,您和GDB是否都同意每个中间步骤的结果。

这是elementary debugging。挑选出给你带来麻烦的陈述,减少其复杂性,直到你找到错误或者可以提出一个非常精确的问题。

(就个人而言,我的下一个“最好的嫌疑人”是,当您说sqrt()时,您的代码和gdb会看到不同的内容。)

答案 1 :(得分:2)

GDB没有正确评估sqrt,如下所示:Why does gdb evaluate sqrt(3) to 0?

答案 2 :(得分:1)

除非使用-O0进行编译,否则无法确定单步执行是否在另一行之后运行一行源代码。您可能在请求表达式评估时,所有参数都未完成,因此结果不可靠。

另一种解释是,表达式的某些参数在生活寄存器中不再存在,因此gdb被愚弄,并且计算错误。