Here are some of the useful, but not widely known, options of GCC that I want to document.

GCC Build Specs

gcc -dumpspecs

Gives the specifications with which GCC was built.

Stack Usage

gcc -fstack-usage

Gives the stack usage function-wise for the compiled translation unit; this is helpful in measuring runtime memory usage. See the manual for details on deciphering its output.

Macros and Include Directories

# get macros defined when the language is C++
cpp -xc++ -dM /dev/null

# get macros defined when the language is C
cpp -dM /dev/null

Prints the macros defined when the preprocessor was called. The last command is popular as gcc -dM -E - << /dev/null but is not as good for two reasons:

  1. If you want to talk to the preprocessor, talk directly to it, why go through the compiler?
  2. Looking at this, one might get a false hope that g++ -dM -E - << /dev/null will spit C++ macros; it doesn’t. Instead one has to do g++ -xc++ -dM -E - << /dev/null for some reasons.

For setting up auto completion in Emacs using Irony, I needed to know the include directories GCC searches. How do we find them?

cpp -xc++ -Wp,-v /dev/null

This prints the list of standard include directories. g++ -v some.cpp would give it too, but this is fast & easy; no input file or fake compiler calls.


g++ -std=c++14 -O3 -c -masm=intel -fverbose-asm -Wa,-adhln=prgm.s prgm.cpp

will show the disassembly of a compilation unit in Intel syntax with inter-weaved source listing. This one is very popular among optimisation enthusiasts 😃 Here’s one more for them.

Class Memory Layout

g++ -fdump-class-hierarchy my_classes.cpp

This would show object memory layout of classes in the source; includes classes with complex inheritance hierarchies.

Optimization Result

With GCC 9 you can check if an optimization was performed or missed (-fopt-info). Example

$ g++ -c -O2 -fopt-info-inline-all note: Considering inline candidate void foreach(T, T, void (*)(E)) [with T = char**; E = char*]/2. optimized:  Inlining void foreach(T, T, void (*)(E)) [with T = char**; E = char*]/2 into int main(int, char**)/1. missed:   not inlinable: void inline_me(char*)/0 -> int std::puts(const char*)/3, function body not available optimized:  Inlined void inline_me(char*)/4 into int main(int, char**)/1 which now has time 127.363637 and size 11, net change of +0.
Unit growth for small function inlining: 16->16 (0%)

Inlined 2 calls, eliminated 1 functions


Use -ftree-vectorize to enable vectorization of loops; this is implicitly enabled at -O3.


If you’re a C or C++ programmer, you should definitely try the sanitizers GCC has (-fsanitize). Some interesting ones

  • Address sanitizer (-fsanitize=address)
  • Leak sanitizer (-fsanitize=leak)
  • Thread sanitizer (-fsanitize=thread)
  • Undefined Behaviour sanitizer (-fsanitize=undefined)

Header Dependency Tree

There’re times when multiple headers with interlinked dependencies are a problem. It’d be easier to understand why a definition is deemed missing by the compiler, despite including a header you think should’ve made it visible. These preprocessor options are your friends:

  • -M show dependencies for all headers
  • -MM show dependencies for non-system headers
  • -H show dependencies as a hierarchy
> g++ -Wall -stc=c++17 -pedantic -H test.cpp

. //XcodeDefault.xctoolchain/usr/include/c++/v1/cmath
.. //XcodeDefault.xctoolchain/usr/include/c++/v1/__config
.. //XcodeDefault.xctoolchain/usr/include/c++/v1/math.h
... //XcodeDefault.xctoolchain/usr/include/c++/v1/__config
... //MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/math.h

What interesting GCC options do you know?