Release中的源文件,Debug中的头文件

时间:2013-06-11 11:29:42

标签: c++ debugging header

我们似乎在我们的应用程序中出现了一种奇怪的情况。正在触发ASSERT,只有在定义了_DEBUG时才会运行,但是在发布模式下编译应用程序时会对其进行评估。

ASSERT在头文件中定义,并从另一个头文件触发,该头文件包含在源文件中。

进一步检查时,源文件确实在Release模式下运行(未定义_DEBUG,NDEBUG是)。但是,头文件已定义_DEBUG,而不是NDEBUG。

根据传统观点,#include头文件等于将代码行剪切并粘贴到源文件中。这会使上述行为变得不可能。

我们正在VS2010中编译大型混合语言(Intel FORTRAN和C ++)应用程序。但是,在我们的构建服务器上也会出现此问题,因此它似乎不仅仅是VS2010的“功能”。

我们检查过:

  1. 所有项目都在发布中构建。
  2. 受影响的cpp文件没有设置任何异常属性。
  3. 我们的解决方案中没有文件手动定义或取消定义_DEBUG或NDEBUG。
  4. 我们通过包含以下条款确定了上述行为:
  5. bool is_debug = false;

    #ifdef _DEBUG

    is_debug = true

    #endif

    然后立即打破这一点。

    我们已经没有什么东西可以测试了 - 关于我甚至可以假设的唯一事情是:

    1. 某些标准库或外部包含正在重新定义_DEGUG和NDEBUG,或
    2. 有些东西覆盖了#include宏(这可能吗?)。
    3. EDIT ---------------------------------------------- ------------

      部分地感谢#error技巧(下面),我们发现了当前的问题:在几个项目中,不再定义NDEBUG和_DEBUG。所有这些项目都是为了从宏$(PreprocessorDefinitions)继承了某些东西 - 但这并没有在任何地方定义。

      这仍然留下一些尴尬的问题:

      1. 导致上述行为 的源文件在其项目设置中定义了NDEBUG,但它们包含的头文件却没有(尽管VS2010会使正确的#ifdef块灰显掉) )。
      2. 如果所有C ++项目(它看起来都是)继承了PreprocessorDefinitions宏,那么为什么不在任何地方定义它?

3 个答案:

答案 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 - 他们所有的意见都是有用的,最终的问题令人沮丧地平凡。