【发布时间】:2013-11-07 06:35:21
【问题描述】:
MSVC 在调试模式下定义_DEBUG,gcc 在发布模式下定义NDEBUG。我可以在 clang 中使用什么宏来检测代码是为发布还是调试而编译?
【问题讨论】:
-
Visual Studio 还使用默认项目设置为发布版本定义了
NDEBUG。
MSVC 在调试模式下定义_DEBUG,gcc 在发布模式下定义NDEBUG。我可以在 clang 中使用什么宏来检测代码是为发布还是调试而编译?
【问题讨论】:
NDEBUG。
如果您查看 IDE 的项目设置,您会发现这些宏实际上是在那里手动定义的,它们不是由编译器自动定义的。事实上,编译器无法真正知道它是在构建“调试”还是“发布”,它只是根据用户(或 IDE)提供给它的标志来构建。
您必须创建自己的宏并手动定义它们,就像 IDE 在创建项目时为您所做的那样。
【讨论】:
-g 用于 gcc / clang。但看起来你是对的,当使用-g 调用时,clang 没有定义任何额外的宏。太糟糕了!
-g 调用编译器时自动定义的宏都可以解决问题。
-g 编译器选项只是说生成调试信息。不幸的是,gcc 将此信息编译为到二进制文件,使它看起来像是编译过程的一部分。 MSC 做了正确的事,简单地生成了一个符号数据库 (pdb) 文件,使区别更容易看到。这与 Debug 构建无关 - 它只是允许从故障转储中获取人类可读的信息。我假设每个人都会为发布的软件生成调试信息。
编译器不定义这些宏。您的 IDE/Makefile/<insert build system here> 可以。这不取决于编译器,而是取决于您使用的环境/构建帮助程序。
约定是在调试模式下定义DEBUG宏,在发布模式下定义NDEBUG宏。
【讨论】:
您可以使用__OPTIMIZE__ 标志来确定是否正在进行优化。这通常意味着它不是调试版本,因为优化通常会重新排列代码序列。尝试逐步执行优化的代码可能会令人困惑。
这可能是那些对这个问题最感兴趣的人真正想要弄清楚的。
【讨论】:
DEBUG、NDEBUG 和类似的宏通常用于将不应出现在最终生产版本中的代码插入调试版本。像额外的错误检查。但由于生产构建几乎总是经过优化,这确实是区分两者的好方法。
在命令行编译器中没有调试模式。这是 IDE 的事情:它只是设置了一些要发送到编译器的选项。
如果你在命令行中使用clang,你可以使用任何你想要的东西。 gcc 也是如此,所以如果你使用 gcc,你可以使用 NDEBUG,你可以使用同样的方法。
【讨论】: