很快,我想知道如果启用-g
,gcc(或g ++。我需要在 C 中,但也对c ++感到好奇)定义了任何特殊符号。可以?如果是这样,有什么符号?
在搜索过程中,我发现:
_DEBUG
是手动定义的(手动我的意思是-D_DEBUG
)并且习惯于Visual C程序员(因为VC在调试模式下编译时定义_DEBUG
)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
的常用选项也会删除我的定义。如果他们不想在调试模式下获取标题,它仍然需要我告诉他们定义它。
答案 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
告诉我没有额外定义的符号。
结合缺少任何说明符号定义的文档,应足以安全地说明没有定义。