为什么c ++应用程序会错误地评估表达式

时间:2013-03-25 03:29:33

标签: c++ qt logic qmake

当我写这个问题时,我突然意识到由于嵌入式和非嵌入式应用程序构建,我们可能使用两个版本的Qt。我们都在使用gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4)。我的构建环境是:

QMake version 2.01a
Using Qt version 4.7.3 in /usr/local/Trolltech/QtEmbedded-4.7.3/lib

至少有一位同事正在使用:

QMake version 2.01a
Using Qt version 4.7.2 in /usr/lib

我的两位同事在制作使用我的计算库的独立应用程序时遇到了问题。我们的主要应用程序和我的独立单元测试应用程序工作正常,我的调查发现我的代码没有问题。我已经得出结论,构建环境或编译器必然存在一些基本问题,因为在这两种情况下我们都会分离出不规则/非标准行为。我分离的案例如下:

void className::functionName(float newDeltaTime)
{
    float zero_ = 0;
    std::cout << "newDeltaTime: " << newDeltaTime << std::endl;
    std::cout << "zero_: " << zero_ << std::endl;
    std::cout << "newDeltaTime > zero_: " << (newDeltaTime > zero_) << std::endl;
    std::cout << "newDeltaTime > zero_: " << (newDeltaTime > zero_) << std::endl;
    std::cout << "newDeltaTime > zero_: " << (newDeltaTime > zero_) << std::endl;
...

输出:

newDeltaTime: 0.2
zero_: 0
newDeltaTime > zero_: 0
newDeltaTime > zero_: 1
newDeltaTime > zero_: 1

使用gdb(由QtCreator运行),我们可以看到每行的正确变量值 - 未损坏。这对我来说真的很奇怪。调试器显示的变量没有变化,但完全相同的表达式第二次产生不同的值。

最初,我有一些错误检查,说if(newDeltaTime > 0) { //do something } else { //log and throw }和我的老板给我看的代码是抛出值为0.2的异常(如上所示)。我无法弄清楚这个问题。当我添加日志记录时,代码开始工作,但我注意到日志记录具有错误的布尔表达式值。最后,我想多次记录表达式,导致上面显示的输出。

我觉得地面不稳定 - 是什么导致这种情况发生?一切都编译没有错误,如果我们两次评估表达式并第二次使用结果,那么它似乎工作正常。当单个事件可能发生翻转时(空间辐射击中电路和危害逻辑),我对投票逻辑很熟悉,但我觉得这里有必要让我感到不快...

1 个答案:

答案 0 :(得分:2)

  

是什么导致这种情况发生?

我唯一能想到的是

  • 您正在使用的编译器(标头)和libstdc++之间的不匹配。
  • 破坏堆栈的信号处理代码

如果你列出的输出总是可重复的,那么第二个原因就不可能了,只有第一个原因仍然存在。

如果您使用非优化代码观察此行为,我将采用的方式:在第一行std::cout << "newDeltaTime > zero_: " <<...行的GDB中设置断点,并在执行该行newDeltaTime后验证不再是0.2。再次重新运行,这次使用watch *(float*)&newDeltaTime设置GDB观察点,并查看值被破坏的确切位置(可能在libstdc ++中的某处)。

如果您只是通过优化代码观察到这一点,那么事情变得更加棘手,您需要先了解ABI和调用约定,然后才能有效地调试它。