如何使DEBUG宏可移植

时间:2013-09-15 22:41:26

标签: c++ visual-studio-2012 portability

我知道“便携式”和“宏”这两个词并不经常在一起,但我的代码通常充斥着#ifdef _DEBUG标签(我使用VS2012)来确认所需的结果。我想让我的代码可以移植到Unix系统。

我的理解基于this post,Visual Studio使用_DEBUG而C标准使用NDEBUG,但它们的功能不同(_DEBUG标记调试mode,NDEBUG标记断言)。

如果我希望我的代码尽可能可移植,如果我只想在断言处于活动状态时运行那些代码行,我是否应该使用#ifndef NDEBUG? Visual Studio中有什么后果?它似乎工作,但我想确保没有什么我想念;即。当有一个非常好的C标准替代品时,为什么微软会使用_DEBUG?历史原因?

4 个答案:

答案 0 :(得分:3)

很久以前那艘船航行了,MSVC顺从了,因为阻力徒劳。这可以按照您的期望工作:

#ifdef NDEBUG
#pragma message("Release build selected")
#endif

那个宏并没有完全从天而降,就像some do一样。项目+属性,C / C ++,预处理器,预处理器定义设置。它的工作原理不是因为编译器加入了Borg,IDE就是这样。或者更具体一点,项目模板确实如此。一个很好的借口:))

所以不,使宏可移植完全不是问题。它只需要你的makefile正确。

答案 1 :(得分:2)

我不知道MS不使用NDEBUG宏的真正原因,而是定义了_DEBUG。我的猜测是它与_ASSERT而不是assert的定义有关。

assert()的问题在于C标准定义要求它在控制台和abort程序中打印一行。但Windows程序通常没有控制台,因此MS认为弹出一个窗口会很好。但是assert()弹出一个窗口将不符合标准,因此开发了一个类似但不同的宏:_ASSERT,以及一个不同的宏来控制其行为:_DEBUG

_UNICODEUNICODE宏存在类似的混乱,但这是另一个故事......

请注意,在Visual C ++项目的默认配置中,在调试模式中定义了_DEBUG,但NDEBUG未定义。在发布模式下,_DEBUG未定义,但NDEBUG是。NDEBUG。因此,对于您自己的代码,您可以使用其中任何一个。但很自然地,如果你想要可移植,你应该使用_DEBUG,因为{{1}}名称是为编译器实现保留的。

答案 2 :(得分:1)

虽然有点做作,但你可以做到这一点,使它有点便携

#if defined(__unix__) && defined(NDEBUG)
#define _DEBUG
#endif

答案 3 :(得分:1)

据我所知,唯一(按标准),NDEBUG应该影响的是assert宏。因此,如果想要添加他们的调试工具,他会添加自己的宏定义,如_DEBUG(不影响或依赖NDEBUG)。

为了使您的调试代码可移植,您可能最好为同样的目的定义自己的宏。

然后作为一个选项,你可以打开和关闭它,比如取决于NDEBUG的存在。