Warning
I am not an adequate coder of C or C++, any information or thoughts provided here could have flaws. Moreover, I only use GNU Compiler Collection (GCC)1, some solutions may not be applicable. Please don’t hesitate to point out my mistakes.
[1] | With GCC 4.8.4 on Gentoo Linux. |
Finding the location of where a macro is defined isn’t hard, just need to know what options to use. I only use GNU Compiler Collection, so this post is only concerning the tools of GCC, in this case, the cpp2, however, you can still use gcc or g++, just put in -E option, which tells compiler to stop after the preprocessing stage.
1 cpp
The command goes like
cpp [-x<c|c++>] [-std=<standard>] -dCHARS <infile>
If input file is from standard input, -, with C++ standard specified, then you will need to include -xc++. Otherwise, the cpp treats the input file as C code and a warning will be thrown.
For the rest of options, from cpp(1):
- -dCHARS
CHARS is a sequence of one or more of the following characters, […].
- M
- Instead of the normal output, generate a list of #define directives for all the macros defined during the execution of the preprocessor, including predefined macros. […]
- D
- Like M except in two respects: it does not include the predefined macros, and it outputs both the #define directives and the result of preprocessing. Both kinds of output go to the standard output file.
- N
- Like D, but emit only the macro names, not their expansions.
- I
- Output #include directives in addition to the result of preprocessing.
- U
- Like D except that only macros that are expanded, or […]
Basically, you probably only need to use M and D, more likely just D. Say, you want to find out how M_PI and other mathematical constants get defined in math.h with gnu99 through this condition:
#if defined __USE_MISC || defined __USE_XOPEN
So, you can run:
% cpp -xc -std=gnu99 -dD /usr/include/math.h | grep -B1 __USE_MISC
#undef __USE_FILE_OFFSET64
#undef __USE_MISC
--
# 311 "/usr/include/features.h" 3 4
#define __USE_MISC 1
It shows the __USE_MISC is defined in that header file, then you can work back up from that header.
You can also get a list of predefined macros in C99 by running
cpp -xc -std=c99 -dM /dev/null
2 Types of locations
If you run:
% cpp -xc -std=c99 - </dev/null
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "<stdin>"
Other than the normal header files, you can see some in angle brackets, which have special meanings.
2.1 <command-line>
It’s what you manually define through command-line options -D, for example:
% cpp -xc -std=c99 -dD -Dfoo=bar /dev/null | grep -B1 foo
# 1 "<command-line>"
#define foo bar
There is a special case that I have seen GCC intentionally defines through command-line:
% cpp -xc++ -std=c++98 -dD /dev/null | grep -B1 GNU_SOURCE
# 1 "<command-line>"
#define _GNU_SOURCE 1
As you can see the standard is C++98 and the command has no manual definition, however, the macro shows up.
2.2 <stdin>
This shows macros are defined through standard input.
% echo '#define foo bar' | cpp -xc -std=c99 -dD - | grep -B1 foo
# 1 "<stdin>"
#define foo bar
2.3 <builtin>
As far as I can tell, they are the predefined macros3 and they could even come from GCC’s compile-time as how Gentoo Linux patches the c-cppbuiltin.c to force a macro defintion. That file name seems to confirm my guess.
[2] | Whenever cpp pops out, the first assocation link my brain gets is to C++, not C preprocessor. |
[3] | diff <(cpp -xc -std=c99 -dM /dev/null | sort) <(cpp -xc -std=c99 -dD /dev/null | sort) |
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.