当指定-g时gcc是否定义了什么?

时间:2011-11-03 16:08:07

标签: c debugging gcc c-preprocessor

很快,我想知道如果启用-g,gcc(或g ++。我需要在 C 中,但也对c ++感到好奇)定义了任何特殊符号。可以?如果是这样,有什么符号?

在搜索过程中,我发现:

  • _DEBUG是手动定义的(手动我的意思是-D_DEBUG)并且习惯于Visual C程序员(因为VC在调试模式下编译时定义_DEBUG
  • 如果NOT不在调试模式下,则定义
  • NDEBUG。虽然我发现有几个地方在说这个,但我在.c和.cpp文件中尝试使用我的gcc和g ++,并且在没有-g的情况下都没有定义这样的符号!

修改:让我演示为什么我不想使用非标准符号:

想象一个内核模块做了什么,并提供了包含在其他内核模块中的头文件,以便它们可以连接到这个。

现在作为一个工具,在我的一个头文件中:

#ifdef DEBUG <-- This is what I need
#define LOG(x, ...) printk("Some extra info"x, ##__VA_ARGS__);
#else
#define LOG(x, ...) printk("Without extra info"x, ##__VA_ARGS__);
#endif

请注意,该名称并非真正LOG,这是一个示例。

现在,我可以自己使用DEBUG的任何符号,但如果有人包含我的标题,他们可能无法定义该符号。当然,我可以告诉他们“顺便说一句,在调试模式中获取标题,定义另一个符号”,但这对我来说听起来不对。

我可以在标题中定义符号并将其包含在所有头文件中。这样,如果它们包含我的一个标题,它们也会得到调试符号。现在的问题是,如果他们想要在调试模式下编译,我的标题仍然认为它们处于调试模式。

所以我认为最好的方法是使用在使用-g时定义的符号,如果有的话!

更新

到目前为止,我得出结论,我可以这样做:

how_to_build.h

#if !defined(NDEBUG)
#define MY_DEBUG
#endif

用法:

#include "how_to_build.h"

#ifdef MY_DEBUG
// rest of the story

这样,NDEBUG的常用选项也会删除我的定义。如果他们不想在调试模式下获取标题,它仍然需要我告诉他们定义它。

3 个答案:

答案 0 :(得分:34)

您可以看到gcc / g ++为任何标志组合定义的所有宏的列表:

$ g++ -E -dD -xc++ /dev/null

例如:

[max@truth ~]$ g++ -E -dD -xc++ /dev/null > a
[max@truth ~]$ g++ -E -dD -xc++ -g -O3 /dev/null > b
[max@truth ~]$ diff a b
1a2
> # 1 "/home/max//"
173c174
< #define __NO_INLINE__ 1
---
> #define __OPTIMIZE__ 1

让我们看看-g是否定义了任何内容:

[max@truth ~]$ g++ -E -dD -xc++ -g /dev/null > c
[max@truth ~]$ diff a c
1a2
> # 1 "/home/max//"

额外的预处理程序指令,但没有-g标志的额外定义。

答案 1 :(得分:16)

正如其他人所说,从the manual可以看出,GCC没有提供任何内在的宏来指示是否会生成调试信息(-g模式)。我想补充的是,这是有目的的。

很久很久以前,GCC的原始作者(RMS,Kenner,可能还有其他几位)决定启用调试信息不​​应导致对实际代码进行任何的更改,以降低风险一个错误mysteriously vanishing when you try to debug it。这是海湾合作委员会的基本设计原则,即使在今天,开发人员仍然竭尽全力维护它。

定义宏会违反此设计原则,因为它会允许源代码在响应-g时自行更改。

答案 2 :(得分:11)

运行
g++ -E -dD -xc++ /dev/null

g++ -E -dD -g -xc++ /dev/null
告诉我没有额外定义的符号。

结合缺少任何说明符号定义的文档,应足以安全地说明没有定义。