GCC dump preprocessor defines

后端 未结 6 2147
既然无缘
既然无缘 2020-11-22 14:28

Is there a way for gcc/g++ to dump its preprocessor defines from the command line? I mean things like __GNUC__, __STDC__, and so on.

相关标签:
6条回答
  • 2020-11-22 15:06

    I usually do it this way:

    $ gcc -dM -E - < /dev/null
    

    Note that some preprocessor defines are dependent on command line options - you can test these by adding the relevant options to the above command line. For example, to see which SSE3/SSE4 options are enabled by default:

    $ gcc -dM -E - < /dev/null | grep SSE[34]
    #define __SSE3__ 1
    #define __SSSE3__ 1
    

    and then compare this when -msse4 is specified:

    $ gcc -dM -E -msse4 - < /dev/null | grep SSE[34]
    #define __SSE3__ 1
    #define __SSE4_1__ 1
    #define __SSE4_2__ 1
    #define __SSSE3__ 1
    

    Similarly you can see which options differ between two different sets of command line options, e.g. compare preprocessor defines for optimisation levels -O0 (none) and -O3 (full):

    $ gcc -dM -E -O0 - < /dev/null > /tmp/O0.txt
    $ gcc -dM -E -O3 - < /dev/null > /tmp/O3.txt
    $ sdiff -s /tmp/O0.txt /tmp/O3.txt 
    #define __NO_INLINE__ 1        <
                                   > #define __OPTIMIZE__ 1
    
    0 讨论(0)
  • 2020-11-22 15:10

    The simple approach (gcc -dM -E - < /dev/null) works fine for gcc but fails for g++. Recently I required a test for a C++11/C++14 feature. Recommendations for their corresponding macro names are published at https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations. But:

    g++ -dM -E - < /dev/null | fgrep __cpp_alias_templates
    

    always fails, because it silently invokes the C-drivers (as if invoked by gcc). You can see this by comparing its output against that of gcc or by adding a g++-specific command line option like (-std=c++11) which emits the error message cc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C.

    Because (the non C++) gcc will never support "Templates Aliases" (see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf) you must add the -x c++ option to force the invocation of the C++ compiler (Credits for using the -x c++ options instead of an empty dummy file go to yuyichao, see below):

    g++ -dM -E -x c++ /dev/null | fgrep __cpp_alias_templates
    

    There will be no output because g++ (revision 4.9.1, defaults to -std=gnu++98) does not enable C++11-features by default. To do so, use

    g++ -dM -E -x c++ -std=c++11 /dev/null | fgrep __cpp_alias_templates
    

    which finally yields

    #define __cpp_alias_templates 200704
    

    noting that g++ 4.9.1 does support "Templates Aliases" when invoked with -std=c++11.

    0 讨论(0)
  • 2020-11-22 15:11

    Late answer - I found the other answers useful - and wanted to add a bit extra.


    How do I dump preprocessor macros coming from a particular header file?

    echo "#include <sys/socket.h>" | gcc -E -dM -
    

    or (thanks to @mymedia for the suggestion):

    gcc -E -dM -include sys/socket.h - < /dev/null
    

    In particular, I wanted to see what SOMAXCONN was defined to on my system. I know I could just open up the standard header file, but sometimes I have to search around a bit to find the header file locations. Instead I can just use this one-liner:

    $ gcc -E -dM -include sys/socket.h - < /dev/null | grep SOMAXCONN
    #define SOMAXCONN 128
    $ 
    
    0 讨论(0)
  • 2020-11-22 15:16

    A portable approach that works equally well on Linux or Windows (where there is no /dev/null):

    echo | gcc -dM -E -
    

    For c++ you may use (replace c++11 with whatever version you use):

    echo | gcc -x c++ -std=c++11 -dM -E -
    

    It works by telling gcc to preprocess stdin (which is produced by echo) and print all preprocessor defines (search for -dletters). If you want to know what defines are added when you include a header file you can use -dD option which is similar to -dM but does not include predefined macros:

    echo "#include <stdlib.h>" | gcc -x c++ -std=c++11 -dD -E -
    

    Note, however, that empty input still produces lots of defines with -dD option.

    0 讨论(0)
  • 2020-11-22 15:17

    Yes, use -E -dM options instead of -c. Example (outputs them to stdout):

     gcc -dM -E - < /dev/null
    

    For C++

     g++ -dM -E -x c++ - < /dev/null
    

    From the gcc manual:

    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. This gives you a way of finding out what is predefined in your version of the preprocessor. Assuming you have no file foo.h, the command

    touch foo.h; cpp -dM foo.h
    

    will show all the predefined macros.

    If you use -dM without the -E option, -dM is interpreted as a synonym for -fdump-rtl-mach.

    0 讨论(0)
  • 2020-11-22 15:22

    While working in a big project which has complex build system and where it is hard to get (or modify) the gcc/g++ command directly there is another way to see the result of macro expansion. Simply redefine the macro, and you will get output similiar to following:

    file.h: note: this is the location of the previous definition
    #define MACRO current_value
    
    0 讨论(0)
提交回复
热议问题