53

Shortly, I want to know if gcc (or g++. I need it in C, but also am curious about c++) defines any special symbols if -g is enabled. Does it? If so, what symbols?

In the search process I found out that:

  • _DEBUG is defined manually (by manually I mean -D_DEBUG) and is a habit taken from Visual C programmers (because VC defines _DEBUG when compiling in debug mode)
  • NDEBUG is defined if NOT in debug mode. Although I found a few places saying this, I tried with my gcc and g++ in .c and .cpp files and in none of them with or without -g no such symbol was defined!

Edit: Let me demonstrate why I don't want to use a non-standard symbol:

Imagine a kernel module that does something and also provides header files to be included in other kernel modules so that they can connect to this one.

Now as a facility, in one of the header files I have:

#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

Note that the name is not really LOG, that's an example.

Now, I can use any symbol for DEBUG myself, but then if someone includes my header, they may not define that symbol. Of course I can tell them "by the way, to get the headers in debug mode, define this other symbol", but that just doesn't sound right to me.

I could define the symbol in a header and include it in all header files. This way, if they include one of my headers, they get the debug symbol too. The problem now is that, if they don't want to compile in debug mode, my headers still think they are in debug mode.

So what I thought would be best was to use a symbol that is defined when -g is used, if there are any!

Update

So far I came to the conclusion that I could do something like this:

how_to_build.h

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

Usage:

#include "how_to_build.h"

#ifdef MY_DEBUG
// rest of the story

This way, the common option of NDEBUG removes my definition also. It still requires me to tell them to define it if they don't want to get the headers in debug mode.

5
  • 2
    The best practise is to always use -g because it doesn't affect optimized code or make it any slower. Also, on Unix it is standard to pass NDEBUG define to the compiler for release builds and define nothing for debug. Hence you should consider using NDEBUG define for telling a debug from release build. Commented Nov 3, 2011 at 16:40
  • @MaximYegorushkin, is it standard or just a convention? If it is standard, how come gcc doesn't do it automatically?
    – Shahbaz
    Commented Nov 3, 2011 at 16:42
  • It is a standard convention. C/C++ language doesn't require defining these symbols. Commented Nov 3, 2011 at 16:45
  • 2
    It's standard in the sense that NDEBUG makes assert.h behave differently.
    – janneb
    Commented Nov 3, 2011 at 17:23
  • "by the way, to get the headers in debug mode, define this other symbol" is the standard way of doing it, IMO. Commented Nov 3, 2011 at 17:46

3 Answers 3

47

You can see the list of all macros gcc/g++ defines for any combination of flags like that:

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

For example:

[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

Let's see whether -g defines anything:

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

Extra preprocessor directive, but no extra macros for -g flag.


This makes sense: -g has no effect on code-gen, only on object-file metadata (debug symbols).

-O0 is "debug mode" code-gen for consistent debugging, as opposed to -Og or higher. (This answer explains what that means in more detail for compilers like gcc and clang: store all variables back to their memory locations after every statement, and don't optimize across statements.)

-O3 and -g are orthogonal (except that you get "optimized out" for some variables when debugging optimized code, and execution appears to jump around between source lines.)

0
34

As others have said, and as is apparent from the manual, GCC does not provide any intrinsic macros that indicate whether debug information will be generated (-g mode). What I want to add, is that this is on purpose.

Long, long ago, the original authors of GCC (RMS, Kenner, probably a couple others) decided that enabling debugging information should not cause any changes whatsoever to the actual code, to reduce the risk of a bug mysteriously vanishing when you try to debug it. This is a bedrock design principle in GCC, and even today the developers go out of their way to maintain it.

Defining a macro would violate this design principle, since it would permit the source code to change itself in response to -g.

1
  • 1
    Very useful answer, good to understand the background to this.
    – jmc
    Commented Apr 13, 2018 at 15:49
12

Running
g++ -E -dD -xc++ /dev/null
vs.
g++ -E -dD -g -xc++ /dev/null
shows me no extra defined symbols.

That, combined with the lack of any documentation stating that symbols get defined, should be enough to safely say that nothing gets defined.

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.