C++ 'true' 和 'false' 关键字在 Visual C++ 6.0 中突然不是真或假
Posted
技术标签:
【中文标题】C++ \'true\' 和 \'false\' 关键字在 Visual C++ 6.0 中突然不是真或假【英文标题】:C++ 'true' and 'false' keywords suddenly not true or false in Visual C++ 6.0C++ 'true' 和 'false' 关键字在 Visual C++ 6.0 中突然不是真或假 【发布时间】:2009-02-04 00:41:15 【问题描述】:我的编译器 (VC++ 6.0 sp6) 显然已经疯了。在某些代码片段中,我看到'bool mybool = true;
'评估并分配为false,反之亦然。将 true/false 关键字更改为 1/0 使其工作正常。相同的代码可以在别处编译,无需更改 true/false 关键字。
什么可能导致这种情况?我的第一个想法是 RAM 或磁盘损坏,但一切都很好。我距离重新格式化我的驱动器并重新安装所有东西不远了,但我很害怕我仍然会看到同样的不当行为。
从技术上讲,某个地方的宏或链接库是否有可能搞砸“true
”和“false
”的含义?
更新: 谜团已揭开。我机器上的环境变量标志设置为“false”,并且由一些预处理器代码插入的方式重新定义了关键字。
【问题讨论】:
您是仅在调试器中单步执行时才看到问题,还是实际上改变了控制流程? 您是否在发布版本的调试器下看到了这个?优化会导致变量的内容非常不可靠。 我们只进行调试构建。我在调试器和正常运行时都看到了同样的错误行为。 感谢您提出这个问题!我实际上有同样的问题,并认为我要疯了! 【参考方案1】:预处理器宏当然可以做到这一点,尽管这会非常令人惊讶。检查是否是这种情况的一种方法是
#ifdef true
# error "true is defined as a macro"
#endif
#ifdef false
# error "false is defined as a macro"
#endif
对 cmets 的回应:
在您看到此行为的地方找到一个非头文件,最好是一个包含很少 #include 的文件。
在包含列表的中间,放置#ifdef #error 指令。
如果错误跳闸,您知道它在包含的前半部分,如果不是,它在后半部分。将一半分成两半并重复。当您将其缩小到一个标题时,打开该标题。如果该标头包含任何标头,则对其包含的标头列表重复该过程。最终你应该能够找到 #defines 。乏味,我同意。
【讨论】:
TRUE 和 FALSE 被定义为宏,但它们的定义是正确的。 ifdef 区分大小写吗?我怎样才能让预处理器告诉我宏是在哪里定义的? #undef true #undef false 确实修复了它。但我不知道搞砸的#defines 在哪里。我试过用正则表达式搜索我能找到的所有头文件,但结果都是空白。【参考方案2】:缓冲区溢出和写入未初始化内存也可能导致此类行为。例如,如果您在相邻的内存位置分配了一个数组和 bool,并且意外写入超出了数组的边界。
【讨论】:
【参考方案3】:如果您在调试器中检查变量值时遇到此问题,并且您正在运行发布版本,则它可能只是调试系统的产物。检查这一点的最简单方法是添加一些代码:
if (mybool)
printf("mybool is true\n");
else
printf("mybool is false\n");
您将能够快速确定调试器是否准确。
【讨论】:
【参考方案4】:首先,VC6 是古老且有缺陷的。在某些情况下,它只会生成不正确的代码,这可能是您问题的答案。如果可以选择,请不要使用 VC6。
其次,您所看到的很可能只是优化的结果。您的代码行为正确吗?如果是这样,只是调试器会感到困惑,因为执行的代码与源代码不同(由于优化)。
【讨论】:
【参考方案5】:头文件很可能正在通过宏翻转值 - 尽管我无法冒险猜测。该文件是否有可能被编译为 C 而其他文件被编译为 C++,并且在某处有一些 #ifdef/#define 代码试图“修复”真/假值,但却弄错了?
【讨论】:
【参考方案6】:我隐约记得,使用 VC6,您可以单独运行预处理器并查看其输出。它可能是编译器开关。
无论如何,这几乎可以肯定是#defines 出错的结果。如果它是内存覆盖,如建议的那样,您可能会看到其他同样奇怪的行为。
【讨论】:
【参考方案7】:从技术上讲,重新定义 bool 是可行的,但我不明白为什么您的特定环境会是唯一出现此问题的环境。
也许有人和你玩得很开心?
【讨论】:
【参考方案8】:这样的问题很可怕,因为你真的没有地方开始。
我要做的第一个测试是在您的项目的所有源代码中搜索同时匹配“#define”和“true”或“#define”和“false”的内容。如果你身边有懂 Perl 的人,那应该是一个快速的脚本。
您是否依赖链接到一些可能已更改的外部库?如果您怀疑您链接的某些东西有些奇怪,您可以尝试以下步骤:
制作一个检查真/假值的程序。 编译此程序,确保将此程序与您的源代码的所有库链接。 运行您的程序,查看您的最小程序是否存在影响您的问题的真/假错误。如果该最小程序存在错误,则您已将问题隔离为您正在执行的链接操作。之后的下一个明显测试是将程序与标准 C++ 库链接,以测试您的编译器是否存在某种错误。
最后,在重新格式化您的机器之前,让其他人编译您的代码。这真的很容易,如果 Perl 脚本没有任何结果,我肯定会向同事寻求帮助。
【讨论】:
【参考方案9】:检查#define true 0
和#define false 1
【讨论】:
【参考方案10】:即使在 Visual Studio 2003 中,有时也会发生在我身上。但我不知道这件事的确切原因。在检查函数的返回值时会发生这种情况。即使我从函数返回 true,但在调用函数中分配返回值时,true 被转换为 false,false 被转换为 true。
在这种情况下,我会检查其他一些输出参数。
【讨论】:
认真的吗?这发生在你身上吗?如果发生这种情况并且您不知道原因,您如何设法编写具有任何程度可预测性的代码? 当我只更改一些遗留代码时。遗留代码不好,它具有程序可能具有的所有缺陷:) 好的。听起来你经常遇到这个问题。 :) 在优化的发布代码上使用调试器并打开调试符号可以得到很多这样的事情。这并不罕见。以上是关于C++ 'true' 和 'false' 关键字在 Visual C++ 6.0 中突然不是真或假的主要内容,如果未能解决你的问题,请参考以下文章