在Visual C ++ 6.0中,C ++'true'和'false'关键字突然不正确或错误

时间:2009-02-04 00:41:16

标签: c++ visual-c++

我的编译器(VC ++ 6.0 sp6)显然已经疯了。在某些代码中,我看到'bool mybool = true;'评估并赋予false,反之亦然。将true / false关键字更改为1/0可以使其正常工作。相同的代码可以在不改变真/假关键字的情况下在其他地方编译。

可能导致这种情况的原因是什么?我的第一个想法是RAM或磁盘损坏,但所有检查都很好。我不远没有重新格式化我的驱动器并重新安装所有东西,但我很害怕我仍然会看到同样的错误行为。

在某个地方使用宏或链接库来解决“true”和“false”的含义在技术上是否可行?

更新: 谜团已揭开。我机器上的环境变量标志设置为'false',并且由一些预处理器代码插入的方式重新定义了关键字。

10 个答案:

答案 0 :(得分:13)

预处理器宏当然可以做到,尽管这会非常令人惊讶。检查是否是这种情况的一种方法是

#ifdef true
#  error "true is defined as a macro"
#endif
#ifdef false
#  error "false is defined as a macro"
#endif

对评论的回应:

查找您看到此行为的非标头文件,最好是少数#includes。

在包含列表的中间,添加#ifdef #error指令。

如果错误跳闸,你知道它是在包含的前半部分,如果没有,则在下半部分。将一半分成两半并重复。当您将其缩小到一个标题时,打开该标题。如果该标头包含任何标头,则重复其包含的标头列表的过程。最终你应该能够找到#defines。单调乏味,我同意。

答案 1 :(得分:5)

缓冲区溢出和写入未初始化的内存也可以解释这种行为。例如,如果您在相邻的内存位置分配了一个数组和bool,并且意外地写入了超出数组范围的内容。

答案 2 :(得分:5)

如果在调试器中检查变量值时遇到此问题,并且您正在运行发布版本,则它可能只是调试系统的工件。检查这个的最简单方法是添加一些代码:

if (mybool)
    printf("mybool is true\n");
else
    printf("mybool is false\n");

您将能够快速确定调试器是否准确。

答案 3 :(得分:4)

首先,VC6是古老而且有缺陷的。在某些情况下,它只会生成错误的代码,这可能是您的问题的答案。如果您有选择,请不要使用VC6。

其次,您所看到的很可能只是优化的结果。您的代码是否正常运行?如果是这样,那只是调试器感到困惑,因为执行的代码与源代码不同(由于优化)。

答案 4 :(得分:3)

最有可能是头文件通过宏翻转值 - 尽管为什么我不能冒险猜测。是否有可能将文件编译为C而其他文件被编译为C ++,并且某些#ifdef / #define代码试图“修复”真值/假值,但却弄错了?

答案 5 :(得分:3)

我依旧回忆起,使用VC6,您可以自行运行预处理器并查看其输出。它可能是编译器开关。

无论如何,这几乎肯定是#defines出错的结果。如果是内存覆盖,正如所建议的那样,你可能会看到其他同样奇怪的行为。

答案 6 :(得分:1)

技术上可以重新定义bool,但我不明白为什么你的特定环境将是唯一一个出现此问题的环境。

也许有人和你玩得开心?

答案 7 :(得分:1)

这样的问题很可怕,因为你真的没有地方可以开始。

我要做的第一个测试是搜索项目的所有源代码,查找与“#define”和“true”或“#define”和“false”匹配的内容。如果你周围有人知道Perl,那应该是一个快速的脚本。

您是否依赖于链接某些可能已更改的外部库?如果您怀疑某些与您链接的内容有些奇怪,您可以尝试以下步骤:

  • 制作一个检查true / false值的程序。
  • 编译此程序,确保将此程序与源代码的所有库链接。
  • 运行您的程序,看看您的最小程序是否显示影响您问题的真/假错误。

如果该最小程序有错误,您已将问题分离到您正在进行链接的事情。之后的另一个明显的测试是将程序与标准C ++库相连接,以测试您的编译器是否有某种错误。

最后,在重新格式化您的机器之前,别人会编译您的代码。这真的很容易,如果Perl脚本没有出现,我肯定会请求同事帮忙。

答案 8 :(得分:0)

检查#define true 0#define false 1

答案 9 :(得分:0)

即使在Visual Studio 2003中,有时它也会发生在我身上。但我不知道确切的原因。检查函数的返回值时会发生这种情况。即使我从函数返回true,在调用函数中分配返回值时,true也会转换为false,false会转换为true。

在这种情况下,我会检查一些其他输出参数。