gcc preprocessor

3.13 Controlling the Preprocessor

Tersified by DGG
Where I have used output, original documentation considers that the output is a makefile and refers to it as "target"

gnu documentation

-E Expand macros and do not invoke the compiler.
-fdirectives-only Do not expand macros.

With -E preprocessing is limited to directives such as #define, #ifdef, and #error, etc.
-dD is implied.

Definition of command line and most builtin macros is disabled.
Macros such as __LINE__, which are contextually dependent, are handled normally.
Enables compilation of files previously preprocessed with -E -fdirectives-only.

-fpreprocessed, takes precedence over -E . This enables full preprocessing of files previously preprocessed with -E -fdirectives-only.

-fpreprocessed Suppress macro expansion, trigraph conversion, escaped newline splicing, and processing of most directives.
Removes comments, a file preprocessed with -C without problems.
Input is preprocessed, The preprocessor acts as a tokenizer for the front ends.
Implied if the input has extension .i, .ii or .mi.
-E -dM With -E, list #define directives for macros, including predefined macros .
To exclude predefined macros use -dD
Without -E a synonym for -fdump-rtl-mach . See (gcc)Developer Options.
-E -dD With -E, excludes predefined macros and outputs both #define and the result of preprocessing to stdout i.e. adds:
# 1 "./application_mode_default.h" 1                         
# 1 "./application_modes.h" 1                             
# 1 "" 1                                
# 1 "" 2                                
# 1 "" 3                                
# 1 "" 1                                
# 1 "app_config.h"                                
# 1 "app_config.h" 2                                  
# 15 "./application_mode_default.h"                       
# 20 "./application_modes.h"                              
# 30 "app_config.h"                               
# 31 "./application_modes.h"                              
# 32 "./application_modes.h" 2                            
# 322 "app_config.h"                                  
# 33 "app_config.h" 2                                 
# 404 "app_config.h"                                  
# 423 "app_config.h"                                  
# 432 "app_config.h"                                  
# 441 "app_config.h" 
# 478 "app_config.h"  
# 487 "app_config.h"   
# 60 "app_config.h"     
-dU #undef macros directives undefined at the time.
As with -dD except only macros that are expanded or whose definedness is tested, are output when they are used or tested.
-traditional-cpp With -E or when invoking CPP explicitly, perform as pre-standard C preprocessors, not as ISO C

Dependencies
-M Describe the dependencies of the main file in the order includes are processed.
Includes those from -include or -imacros.

Formatted as:
object file (without directories), colon source file and included_files

gcc -M -MG app_led.c
app_led.o: app_led.c app_led.h error.h \
  i_gpio.h boards.h task_led.h
Here are the includes same as above (reformatted):
  app_led.h
  error.h
  i_gpio.h
  boards.h
  task_led.h
> grep include app_led.c
#include "app_led.h"1
#include "boards.h"4
#include "error.h"    Redundent since included in app_led.h, so not listed again
#include "i_gpio.h"  Redundent since included in app_led.h, so not listed again
#include "task_led.h"5

> grep include app_led.h 
     # Processed immediately after encountering #include app_led.h in app_led.c 
#include "error.h"2
#include "i_gpio.h"3     
Implies -E and -w to suppresses warnings.
Does not suppress the debug output, such as -dM.
Use -MF file to avoid mixing debug output with the dependency rules or $DEPENDENCIES_OUTPUT
-MM Like -M
omits files from system directories, header files included.
 gcc -M -MG -MM main.c app_led.c
 main.o: main.c app_config.h app_button.h boards.h \
  error.h task_button.h task_gpio.h app_comms.h \
  i_communication.h app_heartbeat.h driver_sensor.h \
  app_led.h i_gpio.h app_log.h app_power.h app_sensor.h \
  i_communication_radio.h task_sensor.h \
  i_environmental_mcu.h i_tmp117.h main.h \
  i_gpio_interrupt.h i_log.h \
  run_integration_tests.h i_power.h \
  i_scheduler.h i_timer.h \
  i_watchdog.h i_yield.h task_flash.h \
  task_led.h task_adc.h
app_led.o: app_led.c app_led.h error.h \
  i_gpio.h boards.h task_led.h testingMacros.h \
  i_log.h
Angle brackets or quotes in an #include do not determine whether that header appears in -MM dependency output.
-MG With -M or -MM
Expected missing header files are generated files and adds them to the dependency list .
The dependency filename is taken directly from the #include directive without prepending paths.
gcc -M -MG main.c 
main.o: main.c app_config.h app_button.h boards.h \
  error.h task_button.h task_gpio.h app_comms.h \
  i_communication.h app_heartbeat.h driver_sensor.h \
  app_led.h i_gpio.h app_log.h app_power.h app_sensor.h \
  i_communication_radio.h task_sensor.h \
  i_environmental_mcu.h i_tmp117.h main.h \
  i_gpio_interrupt.h i_log.h \
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdlib.h \
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/Availability.h \
…
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/secure/_common.h \
  run_integration_tests.h i_power.h \
  i_scheduler.h i_timer.h \
  i_watchdog.h i_yield.h task_flash.h \
  task_led.h task_adc.h
Suppresses preprocessed output.
-MF file With -M or -MM
Specifies file to write the dependency output to.
-Mno-modules Disable dependency generation for compiled module interfaces.
-MP for CPP CPP to add a target for each dependency (other than the main file), causing each to depend on nothing. These work around make errors if header files are removed without updating the Makefile
Typical output:
 test.o: test.c test.h 
    test.h:
Suffix replacment
-MT fileThe output is file
Default: CPP takes the name of the main file and replaces the suffix.
For multiple targets, use multiple -MTs
For example
-MT '$(objpfx)foo.o' results in
         $(objpfx)foo.o: foo.c
-MQ output Like -MT but quotes characters which are special to Make.
-MQ '$(objpfx)foo.o' results in:
          $$(objpfx)foo.o: foo.c
The default output is quoted, as if it were given with -MQ.
-MD Determines file based on -o.
The driver uses its argument with a suffix of .d, otherwise name without directories and suffix replaced with .d
-E (expand macros ) is not implied.
With    -E , -o specifies the dependency output file
Without -E, each -o specifies a target object file.
Used to generate a dependency output file as a side effect of the compilation process.
-MMD Like -MD also supress system headers
-fpch-preprocess Use a precompiled header with -E.
Inserts #pragma GCC pch_preprocess "filename" in the output to mark the place where the precompiled header was found.
When -fpreprocessed is in use, the PCH is loaded.
Off by default, Switched on by -save-temps.
Output is only suitable as input to GCC.
The filename may be absolute or relative. It is safe to edit the filename if the PCH file is available in a different location.
Do not use this #pragma.
-fpch-deps When using pre compiled headers causes the dependency-output flags to list the files from the precompiled headers dependencies.
Default : only the precompiled header are listed and not the files that were used to create it.
-fmacro-prefix-map=old=new Files in directory old expand __FILE__ and __BASE_FILE__ as if the files were in new .
Changes an absolute path to a relative path by using . for new . This results in builds that are location independent.
Affects __builtin_FILE() . See -ffile-prefix-map.
-fnoworking-directory linemarkers are output for current working directory at the time of preprocessing.
After the initial linemarker, a second linemarker with the current working directory followed by two slashes.
GCC uses this directory, when its present in the preprocessed input, as the directory emitted as the current working directory in some debugging information formats.

Implicitly enabled if debugging information is enabled,
If -P is present in the command line, has no effect.

-P Inhibit linemarkers when input is not C.
-A -predicate=answer Make ( cancel ) an assertion with the predicate predicate and answer answer.
Comment Handling
-C Comments are passed to the output file, except for comments in processed directives, which are deleted along with the directive.
Comments are treatmented as tokens.
For example, comments appearing at the start of a directive line, become an ordinary source line, since the first token on the line is no longer a #.
-CC Like -C, Do not discard comments, including during macro expansion.
Comments within macros are also passed
// Comments inside a macro are converted to /* … */

Generally used to support lint comments.

-trigraphs
 Trigraph:       ??(  ??)  ??<  ??>  ??=  ??/  ??'  ??!  ??-
    Replacement:      [    ]    {    }    #    \    ^    |    ~
default, ignored unless in standard-conforming modes . See -std and -ansi
-H Indent header name and precompiled header files to show depth in the #include stack.
Precompiled header file is displayed with ...!
Invalid with 99.
Macro processing
-Ftrack-macro-expansion
              [1|2]
Display macro expansions.
gcc -E -ftr main.c > 0
> grep LOGA 0 
Emit diagnostic about the macro expansion stack when an error occurs.
Probably unnecessary(ed) level of precision of token location tracking decreasing memory .
1 tracks tokens locations in a degraded mode for the sake of minimal memory overhead.
In this mode all tokens resulting from the expansion of an argument of a function-like macro have the same location.
2 tracks tokens locations completely, default.
-dN names of macros are output
-dI ¬ Output #include directives in addition to the result of preprocessing.

Specials

-Xpreprocessor option Pass option as an option to the preprocessor to supply system-specific preprocessor options that are not recognized.
For an option that takes an argument, use -Xpreprocessor twice, once for the option and once for the argument.
-no-integrated-cpp Perform preprocessing as a separate pass before compilation.
Default, GCC performs preprocessing as an integrated part of input tokenization and parsing.
With this the appropriate language front end is invoked twice, once for preprocessing only and once for compilation.
May be useful in with the -B or -wrapper to specify an alternate preprocessor or perform additional processing of the program source between normal preprocessing and compilation.
-fmax-include-depth=depth Set the maximum depth of the nested #include. default: 200.
-flarge-source-files Adjust GCC to expect large source files, at the expense of slower compilation and higher memory usage.
After a large number of lines diagnostics, do not include column numbers and -Wmisleading-indentation ceases to work.
Passing -flarge-source-files increases the number of lines GCC processes before it stops tracking columns.

Character sets

-fexec-charset=charset Set the execution character set for string and character constants. Default: UTF-8. charset can be any encoding supported by the system's iconv library routine.
-fwide-exec-charset=charset Set the wide execution character set, used for wide string and character constants. The default is UTF-32 or UTF-16, whichever corresponds to the width of wchar_t. As with -fexec-charset, charset can be any encoding supported by the system's iconv library routine; avoid encodings that do not fit exactly in wchar_t.
-finput-charset=charset Set the input character set, used for translation from the character set of the input file to the source character set used by GCC.
Default : UTF-8. overridden by the locale or this command-line option, which takes precedence
-pthread Define macros required for the POSIX threads .
Used for both compilation and linking.
-ftabstop=width Width of tabs for column numbers. default : 8. (Don't use TAB characters)
-fextended-identifiers Accept universal character names and extended characters in identifiers.
Default for C99 (and later C standard versions) and C++.
-fdollars-in-identifiers Accept $ in identifiers.
-fno-canonical-system-headers Do not shorten system header paths with canonicalization.

Defining macros

on the command line
-D name Define name as a macro, with a definition of 1 i.e. TRUE.
-D name=definition Processed as if they appeared during translation phase in a #define.
-D'bufferSize=270'  -D'DO_CACHE'  -DUSE_ANTICIPATE ugly ed
Surround an argument list with parentheses before the equals sign
-D'delim(plus,dot)="+","."' 
Escape shell meta-characters.
The definition is truncated by embedded newlines .
-U name Undefine name

-D and -U are processed in order then
-imacros file and -include file .

-imacros file Acquires macros from a header without processing its declarations.
No output is from file.
Processed before -include.
-include file Process as if
#include file
appeared as the first line of the primary source .
The preprocessors working directory is searched for file then , the remainder of the #include search chain.
-include "boards/variants.h"
Processed after -imacros.
-undef Do not predefine system-specific or GCC-specific macros.
Standard predefined macros remain defined.

Version information

On Raspberry pi
gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/6/lto-wrapper
Target: arm-linux-gnueabihf
 Configured with: ../src/configure -v 
--program-suffix=-6 
--program-prefix=arm-linux-gnueabihf- 

--enable-shared 
--enable-linker-build-id 
--without-included-gettext 
--enable-threads=posix 

--prefix=/usr 
--libexecdir=/usr/lib 
--libdir=/usr/lib 
--disable-libitm 

--enable-nls 
--with-sysroot=/ 
--with-system-zlib 
--enable-clocale=gnu 
--enable-libstdcxx-debug 
--enable-libstdcxx-time=yes 
--with-default-libstdcxx-abi=new 
--enable-objc-gc=auto 
--enable-plugin 

--with-fpu=vfp 
--with-float=hard 
 --with-pkgversion='Raspbian 6.3.0-18+rpi1+deb9u1' 
--enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ 
--enable-gnu-unique-object 
--disable-libquadmath 
--disable-browser-plugin 

--enable-gtk-cairo 
--enable-java-awt=gtk 
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-armhf/jre 
--enable-java-home 
--with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-armhf 
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-armhf 
--with-ecj-jar=/usr/share/java/eclipse-ecj.jar 

--with-arch-directory=arm 
--with-target-system-zlib 

--enable-multiarch 
--with-arch=armv6 

--disable-sjlj-exceptions 
--enable-checking=release 


--host=arm-linux-gnueabihf 
--build=arm-linux-gnueabihf 
--target=arm-linux-gnueabihf

--with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs 

Thread model: posix gcc version 6.3.0 20170516 (Raspbian 6.3.0-18+rpi1+deb9u1) Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/8/lto-wrapper

Target: arm-linux-gnueabihf
Configured with: ../src/configure -v
--with-pkgversion='Raspbian 8.3.0-6+rpi1' 
--with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs 

--enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++ 
--prefix=/usr 
--with-gcc-major-version-only 
--program-suffix=-8 
--program-prefix=arm-linux-gnueabihf- 
--enable-shared 
--enable-linker-build-id 
--libexecdir=/usr/lib 
--without-included-gettext 
--enable-threads=posix 
--libdir=/usr/lib 
--enable-nls 
--enable-bootstrap 
--enable-clocale=gnu 
--enable-libstdcxx-debug 
--enable-libstdcxx-time=yes 
--with-default-libstdcxx-abi=new 
--enable-gnu-unique-object 
--disable-libitm 
--disable-libquadmath 
--disable-libquadmath-support 
--enable-plugin 
--with-system-zlib 
--with-target-system-zlib 
--enable-objc-gc=auto 
--enable-multiarch 
--disable-sjlj-exceptions 
--with-arch=armv6 
--with-fpu=vfp 
--with-float=hard 
--disable-werror 
--enable-checking=release 

--host=arm-linux-gnueabihf 
--build=arm-linux-gnueabihf 
--target=arm-linux-gnueabihf

Thread model: posix gcc version 8.3.0 (Raspbian 8.3.0-6+rpi1)
on mac os version 12.0
Configured with: 
--prefix=/Library/Developer/CommandLineTools/usr 
--with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.0 (clang-1200.0.32.29)
Target: x86_64-apple-darwin21.0.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

Original version GNU.org

There are additional options to control search paths for include files documented in Directory Options.

Options to control diagnostics are listed in Warning Options -fsyntax-only -fmax-errors=n -w inhibit warnings -Werror all warning -> error -Werror=switch -Wno-error=switch NOT error even with -Werror -Wfatal-errors Abort on first error -Wimplicit warnings on implicit declarations -Wno-implicit -Wall enables many including: -Wunused which enables -Wunused-value comment, maybe-uninitialized, misleading-indentation , multistatement-macros -Wextra even more than Wall -Wno-cpp Suppress #warnings good things>: -Wformat=n printf, scanf check args -Wmisleading-indentation example :if (some_condition ()) foo (); bar (); /* looks like bar is included in if but it isnt */ -Wmissing-braces initializer