>_cmd.script

g++

GNU C++ compiler front end

Development

By CMD Script Team · 5 min read · Last updated

SYNTAX
g++ [OPTIONS] FILE...

Options

Command options and flags
FlagDescription
-o FILEWrite the compiled output to FILE instead of the default a.out
-cCompile and assemble into an object file (.o) without linking
-WallEnable a broad set of commonly useful compiler warnings
-gInclude debugging symbols in the output, needed for source-level debugging with gdb
-std=c++17Select the C++ language standard to compile against, e.g. c++11, c++14, c++17, c++20
-O2Enable a strong level of optimization for release builds
-I DIRAdd DIR to the list of directories searched for #include header files
-l NAMELink against library libNAME (e.g. -lpthread links the POSIX threads library)

Distribution compatibility

  • Ubuntu
  • Debian
  • Fedora
  • Arch
  • macOS (g++ is often aliased to Clang via Xcode Command Line Tools; install real GCC via Homebrew for full GCC behavior)

What it does

g++ is the GNU Compiler Collection's front end for C++ — the companion to gcc that compiles, assembles, and links C++ source into object files or executables. It shares the same underlying compiler infrastructure as gcc but is specialized for C++: it treats input files as C++ by default, applies C++ language semantics (name mangling, templates, classes, exceptions), and automatically links against the C++ standard library (libstdc++), which plain gcc does not do on its own.

Beginner examples

  • g++ main.cpp — compile and link into a default executable named a.out
  • g++ -o app main.cpp — compile and link, naming the output app
  • g++ -c main.cpp — compile to an object file main.o without linking
  • g++ -Wall -o app main.cpp — compile with common warnings enabled
  • g++ -std=c++17 -o app main.cpp — compile explicitly targeting the C++17 standard
g++ -std=c++17 -Wall -o app main.cpp

Advanced examples

  • Build a multi-file C++ project by compiling each translation unit separately, then linking: g++ -std=c++17 -c a.cpp b.cpp && g++ -o app a.o b.o
  • Optimize for release while keeping warnings visible: g++ -O2 -Wall -std=c++17 -o app main.cpp
  • Compile a multi-threaded program correctly, including required compiler flags: g++ -std=c++17 -pthread -o app main.cpp
  • Add a header search path for a library installed in a non-standard location: g++ -I/usr/local/include -std=c++17 -o app main.cpp
  • Enforce a clean build with warnings treated as errors in CI: g++ -Wall -Wextra -Werror -std=c++17 -o app main.cpp
g++ -std=c++20 -Wall -Wextra -g -O0 -o app main.cpp

Common mistakes

  • Using gcc instead of g++ to link a C++ program, causing "undefined reference" errors for standard library symbols (like std::cout) because gcc doesn't automatically link libstdc++ the way g++ does.
  • Omitting -std= and relying on the compiler's shifting default C++ standard, leading to inconsistent behavior or available features across different g++ versions or machines.
  • Using -lpthread alone for multi-threaded code instead of -pthread, missing compiler-side flags that -pthread also sets for correct thread-safe compilation.
  • Compiling with -O2 while trying to step through code in a debugger — optimizations can make source-level debugging confusing; use -O0 -g while actively debugging.
  • Forgetting that -c stops before linking, so a one-shot g++ -c main.cpp command won't produce a runnable executable, only an object file.

Tips

  • Always pin an explicit -std= (e.g. -std=c++17 or -std=c++20) rather than relying on the compiler's default, so behavior stays consistent across environments and compiler upgrades.
  • Use g++, not gcc, whenever you're compiling or linking C++ code, to ensure libstdc++ is linked automatically.
  • Prefer -pthread over a bare -lpthread for multi-threaded programs, since it applies additional compiler flags needed for thread safety, not just the library link.
  • Keep -Wall -Wextra on by default during development to catch subtle C++ pitfalls (like unused variables or signed/unsigned comparisons) early.

Best practices

  • Compile with -Wall -Wextra enabled as standard practice, and address the warnings rather than suppressing them.
  • Pin a specific -std= value in your build configuration (Makefile, CMakeLists.txt) so the targeted C++ standard doesn't silently drift between compiler versions.
  • Keep debug builds (-g -O0) and release builds (-O2, stripped or with separate debug info) clearly separated in your build system rather than reusing one flag set for both.
  • For any project with more than a couple of files, drive the build with make (or another build system) rather than typing out manual multi-file g++ invocations.

Try it yourself

A simulated shell with a sample home directory — experiment freely, nothing leaves your browser. Type help to list supported commands.

Real-world use cases

  • Compiling a C++ project's source files into object files and linking them into a final executable, typically orchestrated by a Makefile or CMake.
  • Building a debug build with -g -O0 to investigate a crash with gdb.
  • Producing an optimized -O2 release build of a performance-sensitive C++ application.
  • Compiling multi-threaded server or application code with -pthread to ensure correct thread-safe compilation and linking.

Common interview questions

  • What's the difference between gcc and g++? Both are front ends to the same GNU compiler infrastructure, but g++ treats source as C++ by default and automatically links the C++ standard library (libstdc++); using gcc to link C++ code typically produces undefined reference errors for standard library symbols because that automatic link doesn't happen.
  • Why should you always specify -std= explicitly? Because the compiler's default C++ standard can vary between versions and platforms, so pinning it (e.g. -std=c++17) keeps the project's language features and behavior consistent across build environments.
  • What's the difference between -pthread and -lpthread? -lpthread only links the pthread library, while -pthread additionally sets compiler flags required for correct thread-safe code generation, so -pthread is generally the safer, preferred choice for multi-threaded C++ programs.
  • Why avoid -O2 while actively debugging? Because optimizations can reorder, inline, or eliminate code in ways that make source-level debugging misleading; -O0 keeps generated code closely aligned with the source for accurate stepping and variable inspection.

Frequently Asked Questions

What's the difference between gcc and g++?

gcc and g++ are both front ends to the same underlying GNU compiler collection, but g++ treats source files as C++ by default, automatically links against the C++ standard library (libstdc++), and enables C++-specific language features and defaults. Using gcc on a .cpp file compiles it as C++ (via the g++ frontend logic for that extension) but does not automatically link libstdc++, which is a common source of 'undefined reference' errors for things like std::cout.

Why do I need -std=c++17 (or another version)?

Without an explicit -std= flag, g++ falls back to its own default language standard, which varies between compiler versions and can silently change which language features are available or how some constructs behave. Pinning -std=c++17 (or whichever standard your project targets) keeps builds consistent across machines and compiler upgrades.

How do I fix undefined reference errors for std:: functions?

Make sure you're using g++ (not gcc) to link, since g++ automatically links libstdc++ where gcc does not. If you're compiling with threads, also check whether -lpthread (or -pthread) is needed, and confirm any third-party libraries are linked with -l after your source/object files.

What does -pthread do that -lpthread doesn't?

-pthread not only links the pthread library but also sets compiler flags needed for correct thread-safe code generation (such as defining _REENTRANT), so it's generally preferred over a bare -lpthread when building multi-threaded C++ programs.

Cheat sheet

Download a quick-reference cheat sheet for g++.