This page is about the GNU Compiler Collection, or GCC.

Simple command line usage

Compile C++ source code and produce an object file. The -c flag prevents the linker to be invoked. The -o flag names the output file.

g++ -c foo.cpp -o foo.o

Link a few object files and produce a shared library. Note that the name of the library must be fully specified, i.e. the prefix "lib" and the extension ".so" are not provided automagically if they are omitted.

g++ -shared foo.o bar.o -o libFoobar.so

Same thing, but produce a program. Note that the linker automatically links against libstdc++ if it produces an executable program.

g++ foo.o bar.o main.o -o foobar

Compile and link with one invocation:

g++ -shared foo.cpp bar.cpp -o libFoobar.so
g++ foo.cpp bar.cpp main.cpp -o foobar

Static libraries

Static libraries are not produced by GCC. Instead the various object files generated by GCC are simply patched together with the ar command and then processed by ranlib. The following commands produce the static library libFoobar.a:

ar cru libFoobar.a foo.o bar.o
ranlib libFoobar.a

File extension vs. compiler/linker name

GCC assumes from the extension of a file what source code it contains and therefore what kind of compilation needs to be done.

  • .c = C source code which needs to be preprocessed
  • .i = C source code which should not be preprocessed
  • .cpp = C++ source code which needs to be preprocessed
  • .ii = C++ source code which should not be preprocessed
  • .m = Objective-C source code which needs to be preprocessed
  • .mi = Objective-C source code which should not be preprocessed
  • .mm = Objective-C++ source code which needs to be preprocessed
  • .mii = Objective-C++ source code which should not be preprocessed
  • .h = C, C++, Objective-C or Objective-C++ header file to be turned into a precompiled header
  • A few other extensions :-)
  • Anything with an unrecognized extension is assumed to be an object file that needs to be passed to linker

Instead of letting the compiler assume the programming language from the file extension, the -x command line option can be used to explicitly specify the language. Possible values:

  • c
  • c++
  • objective-c
  • objective-c++
  • A few other languages :-)

Invoking the compiler under different names also influences what type of compilation and linking is done:

  • gcc: The normal rules as explained above apply. When linking, however, the C++ library is not added automatically. This results in failure when the linker should produce an executable program.
  • g++: Treats .c, .h and .i files as C++ files (unless -x is used) and automatically specifies linking against the C++ library (-lstdc++)

Preprocessor stuff

If the command line argument -M is specified, the preprocessor lists all files that are included via the #include preprocessor statement. No compiling is done in this mode, processing stops after the preprocessing stage as if the -E flag had been passed.

Dry run

The command line argument -### can be used to execute a "dry run", i.e. no preprocessing, compiling, linking etc. is actually done. Instead the commands executed to run each stage of compilation is printed to standard error. This is useful to see what the compiler actually does. The commands printed to standard error are suitable to be used in a shell script.

If compilation should be executed but you only want to see what the compiler really does, specify the -v flag.

Symbol visibility in C++

See the Mac OS X Programming page.

C++ name mangling / decoration

Use the utility c++filt to de-mangle or un-decorate a C++ symbol:

nargothrond:~ --> c++filt __ZNK5boost6system14error_category10equivalentERKNS0_10error_codeEi
boost::system::error_category::equivalent(boost::system::error_code const&, int) const


Forward declaring I/O related classes from the C++ standard library (e.g. std::istream)

I/O related classes from the C++ standard library, such as std::istream or std::ostream, are declared as typedefs, so it is practically impossible to forward declare these types in a header file. The official way how to do this is to include a very light-weight header which only contains the typedef declarations themselves:

#include <iosfwd>