C++ 版本中的源文件,调试中的头文件
我们的应用程序似乎出现了一种奇怪的情况。正在触发一个断言,该断言仅在定义了_DEBUG的情况下运行,但在发布模式下编译应用程序时将对其进行评估 断言是在头文件中定义的,并从另一个头文件触发,该头文件包含在源文件中 进一步检查后,源文件确实是在发布模式下运行的(没有定义调试,NDEBUG是)。但是,头文件定义了_DEBUG,而不是NDEBUG 根据传统智慧,包含头文件等于将代码行剪切并粘贴到源文件中。这将使上述行为不可能发生 我们正在VS2010中编译一个大型混合语言(英特尔FORTRAN和C++)应用程序。不过,这个问题也发生在我们的构建服务器上,所以它似乎不仅仅是VS2010的“特性” 我们检查了:C++ 版本中的源文件,调试中的头文件,c++,debugging,header,C++,Debugging,Header,我们的应用程序似乎出现了一种奇怪的情况。正在触发一个断言,该断言仅在定义了_DEBUG的情况下运行,但在发布模式下编译应用程序时将对其进行评估 断言是在头文件中定义的,并从另一个头文件触发,该头文件包含在源文件中 进一步检查后,源文件确实是在发布模式下运行的(没有定义调试,NDEBUG是)。但是,头文件定义了_DEBUG,而不是NDEBUG 根据传统智慧,包含头文件等于将代码行剪切并粘贴到源文件中。这将使上述行为不可能发生 我们正在VS2010中编译一个大型混合语言(英特尔FORTRAN和C++
bool是\u debug=false代码>
\ifdef\u调试
is_debug=true
#endif
然后马上就说到点子上了
我们没有什么东西可以测试了——我甚至可以假设的只有:
一些标准库或外部包含正在重新定义_deug和NDEBUG,或
有东西覆盖了#include宏(这可能吗?)
编辑----------------------------------------------------------
部分由于#错误技巧(见下文),我们发现了直接的问题:在一些项目中,不再定义NDEBUG和#u DEBUG。所有这些项目都是为了从宏$(PreprocessorDefinitions)继承一些东西,但这在任何地方都没有定义
这仍然留下一些尴尬的问题:
导致上述行为的源文件在其项目设置中确实定义了NDEBUG,但它们包含的头文件却没有定义(尽管VS2010会灰显正确的#ifdef块)
如果预处理定义宏是由所有C++项目继承的(它看起来是),那么为什么它没有在任何地方定义?
我处理此类问题的通常方法是,查看符号的定义位置或使用了\ifdef
,然后在其中放入“error Some text”。这样编译过程就会中断,而不必等待并运行它。然后你可以看到真正的定义
您还可以在断言出现的地方添加这样一个“ifdef-”错误组合,这样您就可以完全确定编译器认为什么是有效的。来源:
断言例程在C运行时库的发行版和调试版中都可用。另外两个断言宏_ASSERT和_ASSERTE也可用,但它们仅在定义了_DEBUG标志时计算传递给它们的表达式
换句话说:要么使用_ASSERT(…)要么#define NDEBUG,这样你就不会在发布版本中得到断言。好吧,问题是因为在多个项目的属性->C/C++->>预处理器->预处理器定义中缺少NDEBUG和_DEBUG。它们是否总是丢失,或者它们是否最初是通过$(PreprocessorDefinitions)宏包含的,目前尚不清楚
多亏了@Lamza、@Devolus和@Werner Henze,他们所有的输入都是有用的,最终的问题是令人沮丧的普通问题。您是否尝试过F12,并将光标放在调试上?(转到符号的定义)提示不错,但在本例中,它找不到定义:-(抱歉:我应该说得更清楚。我们正在一个头文件中定义ASSERT,如果定义了NDEBUG,则将其设置为空函数,如果没有,则将其设置为实函数。谢谢@Devulus-我们还没有解决这个问题,但这一技巧为我们提供了更多的证据。看起来,该头文件的每个包含都以某种方式包含在其中未定义NDEBUG。