C++ 版本中的源文件,调试中的头文件

C++ 版本中的源文件,调试中的头文件,c++,debugging,header,C++,Debugging,Header,我们的应用程序似乎出现了一种奇怪的情况。正在触发一个断言,该断言仅在定义了_DEBUG的情况下运行,但在发布模式下编译应用程序时将对其进行评估 断言是在头文件中定义的,并从另一个头文件触发,该头文件包含在源文件中 进一步检查后,源文件确实是在发布模式下运行的(没有定义调试,NDEBUG是)。但是,头文件定义了_DEBUG,而不是NDEBUG 根据传统智慧,包含头文件等于将代码行剪切并粘贴到源文件中。这将使上述行为不可能发生 我们正在VS2010中编译一个大型混合语言(英特尔FORTRAN和C++

我们的应用程序似乎出现了一种奇怪的情况。正在触发一个断言,该断言仅在定义了_DEBUG的情况下运行,但在发布模式下编译应用程序时将对其进行评估

断言是在头文件中定义的,并从另一个头文件触发,该头文件包含在源文件中

进一步检查后,源文件确实是在发布模式下运行的(没有定义调试,NDEBUG是)。但是,头文件定义了_DEBUG,而不是NDEBUG

根据传统智慧,包含头文件等于将代码行剪切并粘贴到源文件中。这将使上述行为不可能发生

我们正在VS2010中编译一个大型混合语言(英特尔FORTRAN和C++)应用程序。不过,这个问题也发生在我们的构建服务器上,所以它似乎不仅仅是VS2010的“特性”

我们检查了:

  • 所有项目都在发布中构建
  • 受影响的cpp文件未设置任何异常属性
  • 我们的解决方案中没有手动定义或取消定义_DEBUG或NDEBUG的文件
  • 我们通过包括以下条款确定了上述行为:
  • 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。