我们的应用程序似乎出现了一种奇怪的情况。一个 ASSERT 被触发,它应该只在定义了 _DEBUG 的情况下运行,但是当应用程序在发布模式下编译时它正在被评估。
ASSERT 定义在一个头文件中,并被另一个头文件触发,该头文件包含在源文件中。
进一步检查,源文件确实在发布模式下运行(_DEBUG 未定义,NDEBUG 已定义)。但是,头文件定义了 _DEBUG,而不是 NDEBUG。
按照传统观念,#include 一个头文件就等于将代码行剪切并粘贴到源文件中。这将使上述行为成为不可能。
我们正在 VS2010 中编译一个大型的混合语言(英特尔 FORTRAN 和 C++)应用程序。不过,这个问题也出现在我们的构建服务器上,所以它似乎不仅仅是 VS2010 的“功能”。
我们检查了:
- 所有项目都在 Release 中构建。
- 受影响的 cpp 文件没有设置任何异常属性。
- 我们的解决方案中没有手动定义或取消定义 _DEBUG 或 NDEBUG 的文件。
- 我们通过包含以下条款来确立上述行为:
bool is_debug = false;
#ifdef _DEBUG
is_debug = true
#endif
并在之后立即打破这一点。
我们要测试的东西已经不多了——我什至可以假设的唯一事情是:
- 某些标准库或外部包含正在重新定义 _DEGUG 和 NDEBUG,或者
- 某些东西覆盖了#include 宏(这可能吗?)。
编辑 - - - - - - - - - - - - - - - - - - - - - - - - - ---------
部分感谢#error 技巧(如下),我们发现了直接的问题:在几个项目中,NDEBUG 和_DEBUG 不再定义。所有这些项目都意味着从宏 $(PreprocessorDefinitions) 继承了一些东西——但这并没有在任何地方定义。
这仍然留下了一些尴尬的问题:
- 导致上述行为的源文件确实在其项目设置中定义了 NDEBUG,但它们包含的头文件没有(尽管 VS2010 确实将正确的 #ifdef 块灰显)。
- 如果 PreprocessorDefinitions 宏被所有 C++ 项目(它似乎是)继承,那么为什么不在任何地方定义它?