Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know (in GCC) when given macro/preprocessor symbol gets declared?

Suppose I have #define foo in various header files. It may expand to some different things. I would like to know (when compiling a .cc file) when a #define is encountered, to what it will expand, it which file it is and where it got included from.

Is it possible? If not, are there any partial solutions that may help?

Feel free to add comments with clarification requests.

Edit: current answers seem to concentrate on the case when there is one #define and I just want to jump to definition or know what the definition is. That's the simple case and yes, your solutions work. But when I have the same #define in different files, and want to know which one kicks in first, none of these techniques is useful. Okay, I actually used #warning carefully to find the right place. But this requires much work.

like image 372
Paweł Hajdan Avatar asked Nov 14 '08 18:11

Paweł Hajdan


People also ask

What is __ GNUC __?

__GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ These macros are defined by all GNU compilers that use the C preprocessor: C, C++, Objective-C and Fortran. Their values are the major version, minor version, and patch level of the compiler, as integer constants. For example, GCC version x . y .

What does ## mean in C preprocessor?

The double-number-sign or token-pasting operator (##), which is sometimes called the merging or combining operator, is used in both object-like and function-like macros. It permits separate tokens to be joined into a single token, and therefore, can't be the first or last token in the macro definition.

What is __ Size_type __?

Note that __SIZE_TYPE__ isn't a variable; it's a type. Compilers other than GCC probably do not provide it, unless they're trying to be compatible with GCC. If you want size_t , include <stddef. h> if you aren't including any of the other headers (such as <stdio. h> , <string.

What is the GCC option that runs only the preprocessor?

The -E option causes gcc to run the preprocessor, display the expanded output, and then exit without compiling the resulting source code.


5 Answers

Use -E :

# shows preprocessed source with cpp internals removed
g++ -E -P file.cc
# shows preprocessed source kept with macros and include directives 
g++ -E -dD -dI -P file.cc  

The internals above are line-markers for gcc which are kinda confusing when you read the output. -P strips them

 -E  Stop after the preprocessing stage; do not run the compiler proper.  
     The output is in the form of preprocessed source code, which is sent to the 
     standard output.

     Input files which don't require preprocessing are ignored.

Note: comments correctly complain this is only a partial solution. It won't tell you when a macro will be replaced. It shows you the preprocessed source, which can be helpful anyway.

like image 56
Johannes Schaub - litb Avatar answered Oct 05 '22 02:10

Johannes Schaub - litb


I would like to know (when compiling a .cc file) when a #define is encountered,

I know a solution to that. Compile the file with the symbol already defined as illegal C++ code (the article linked to uses '@'). So, for GCC you would write

gcc my_file.c -Dfoo=@

When that expands it's guaranteed to cause a syntax error, and the compiler should tell you which file that syntax error is in, which will be very helpful.

If you use the trick Raymond Chen suggests, the compiler may tell you where the "conflicting" definition came from, and may give you a list of how it got included. But there's no guarantee. Since I don't use macros (I prefer const and enum) I can't say if GCC is one of the smarter compilers in this regard. I don't believe the C or C++ standards say anything about this, other than once the preprocessor runs you lose all sorts of useful information.

like image 40
Max Lybbert Avatar answered Oct 05 '22 01:10

Max Lybbert


It wont help you find where it was defined but you can see the definition for a particular file by using the -E -dM flags

g++ -E -dM file.cpp | grep MACRO
like image 36
Martin York Avatar answered Oct 05 '22 02:10

Martin York


for the "to what it will expand" I use the -E switch in gcc which gives the preprocessed output. But there is no backtrace which macro came where from (or if there was a macro at all).

Another option you might use is -g3, this adds debug information regarding the macros, i.e. you can later see in your debugger the definition of each macro.

like image 22
flolo Avatar answered Oct 05 '22 02:10

flolo


A Good IDE can do this for you on demand via some form of jump to definition.

like image 41
Brian Avatar answered Oct 05 '22 03:10

Brian