Say I use some C or C++ library, made out of headers and some source files, that are compiled into a static or shared library I can link with.
In the headers of the library (dozens... or hundreds of files), some macros/symbols are defined.
Now I want to use this library in a project, that also defines some macros and symbols. Of course, I want to avoid name collisions, as this has been reported sometimes, particularly with windows.h. But more generally I want to keep control of what is really exported out of that header.
I can produce a list of defined symbols with gcc preprocessor options:
gcc -E -dM include/great_lib.h | sort -V >symbols.txt
This outputs in file symbols.txt a sorted list of all the defined symbols included in a user file when it includes this header.
However, it only gives the symbol, not the file where it was defined.
I have the feeling that this could be a useful information. For example, to check if some system macro is being redefined in "great_lib.h" or its ascendants. Unfortunalty, after checking gcc preprocessor options, I don't see a way to do that using gcc.
For example, instead of only giving me:
#define M_PI 3.14159265358979323846
it would produce
#define M_PI 3.14159265358979323846; /usr/include/math.h
Maybe something with the -dN option ? But its output is confusing for me, it requires further text processing, and I don't understand how the information is layered. Or a simpler way ?
Related questions:
Preprocessor directives appear in source code. There are many different directives. One of them is #include , which is used to include a header file. Header files contain a collection of declarations, often for functions and types (and sometimes variables) found in a library. However, a header is not a library.
The #define directive causes the compiler to substitute token-string for each occurrence of identifier in the source file. The identifier is replaced only when it forms a token. That is, identifier is not replaced if it appears in a comment, in a string, or as part of a longer identifier.
All Preprocessor directives begin with the # (hash) symbol. C++ compilers use the same C preprocessor. The preprocessor is a part of the compiler which performs preliminary operations (conditionally compiling code, including files etc...) to your code before the compiler sees it.
In computer science, a preprocessor (or precompiler) is a program that processes its input data to produce output that is used as input to another program. The output is said to be a preprocessed form of the input data, which is often used by some subsequent programs like compilers.
The -dD option outputs the preprocessed source along with the macros. This includes lines that indicate the current source file, e.g.
# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.5.2/../../../../include/_mingw.h" 1 3
You can write a little program that (i) keeps track of the current source file by parsing these lines; (ii) outputs all lines that start with #define
(and \t# define
etc.), followed by the current source filename; (iii) discards all other lines (the source code, declarations etc.).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With