我们似乎在我们的应用程序中出现了一种奇怪的情况。正在触发ASSERT,只有在定义了_DEBUG时才会运行,但是在发布模式下编译应用程序时会对其进行评估。
ASSERT在头文件中定义,并从另一个头文件触发,该头文件包含在源文件中。
进一步检查时,源文件确实在Release模式下运行(未定义_DEBUG,NDEBUG是)。但是,头文件已定义_DEBUG,而不是NDEBUG。
根据传统观点,#include头文件等于将代码行剪切并粘贴到源文件中。这会使上述行为变得不可能。
我们正在VS2010中编译大型混合语言(Intel FORTRAN和C ++)应用程序。但是,在我们的构建服务器上也会出现此问题,因此它似乎不仅仅是VS2010的“功能”。
我们检查过:
bool is_debug = false;
#ifdef _DEBUG
is_debug = true
#endif
然后立即打破这一点。
我们已经没有什么东西可以测试了 - 关于我甚至可以假设的唯一事情是:
EDIT ---------------------------------------------- ------------
部分地感谢#error技巧(下面),我们发现了当前的问题:在几个项目中,不再定义NDEBUG和_DEBUG。所有这些项目都是为了从宏$(PreprocessorDefinitions)继承了某些东西 - 但这并没有在任何地方定义。
这仍然留下一些尴尬的问题:
答案 0 :(得分:2)
我对此类问题的常用方法是,查看符号的定义位置或使用#ifdef
,然后将“#error some text”放入其中。这种方式已经使编译过程中断,而不必等待并运行它。然后你可以看到真正定义的内容。
您还可以在发生断言的地方添加#ifdef - #error组合,然后您可以完全确定编译器认为应该有效的内容。
答案 1 :(得分:0)
来自http://msdn.microsoft.com/en-us/library/9sb57dw4(v=vs.71).aspx:
断言例程在C运行时库的发行版和调试版中都可用。另外两个断言宏_ASSERT和_ASSERTE也可用,但它们只评估在定义了_DEBUG标志时传递给它们的表达式。
换句话说:要么使用_ASSERT(...),要么使用#define NDEBUG,这样就不会在Release版本中获得断言。
答案 2 :(得分:0)
好的,问题原来是因为在几个项目的属性 - > C / C ++ - >预处理器 - >预处理器定义中缺少NDEBUG和_DEBUG。它们是否总是丢失,或者它们是否最初是通过$(预处理器定义)宏包含的还不清楚。
感谢@ Lamza,@ Devolus和@Werner Henze - 他们所有的意见都是有用的,最终的问题令人沮丧地平凡。