g++
GNU C++ compiler front end
By CMD Script Team · 5 min read · Last updated
g++ [OPTIONS] FILE...Options
| Flag | Description |
|---|---|
-o FILE | Write the compiled output to FILE instead of the default a.out |
-c | Compile and assemble into an object file (.o) without linking |
-Wall | Enable a broad set of commonly useful compiler warnings |
-g | Include debugging symbols in the output, needed for source-level debugging with gdb |
-std=c++17 | Select the C++ language standard to compile against, e.g. c++11, c++14, c++17, c++20 |
-O2 | Enable a strong level of optimization for release builds |
-I DIR | Add DIR to the list of directories searched for #include header files |
-l NAME | Link 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 nameda.outg++ -o app main.cpp— compile and link, naming the outputappg++ -c main.cpp— compile to an object filemain.owithout linkingg++ -Wall -o app main.cpp— compile with common warnings enabledg++ -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
gccinstead ofg++to link a C++ program, causing "undefined reference" errors for standard library symbols (likestd::cout) becausegccdoesn't automatically linklibstdc++the wayg++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
-lpthreadalone for multi-threaded code instead of-pthread, missing compiler-side flags that-pthreadalso sets for correct thread-safe compilation. - Compiling with
-O2while trying to step through code in a debugger — optimizations can make source-level debugging confusing; use-O0 -gwhile actively debugging. - Forgetting that
-cstops before linking, so a one-shotg++ -c main.cppcommand won't produce a runnable executable, only an object file.
Tips
- Always pin an explicit
-std=(e.g.-std=c++17or-std=c++20) rather than relying on the compiler's default, so behavior stays consistent across environments and compiler upgrades. - Use
g++, notgcc, whenever you're compiling or linking C++ code, to ensurelibstdc++is linked automatically. - Prefer
-pthreadover a bare-lpthreadfor multi-threaded programs, since it applies additional compiler flags needed for thread safety, not just the library link. - Keep
-Wall -Wextraon by default during development to catch subtle C++ pitfalls (like unused variables or signed/unsigned comparisons) early.
Best practices
- Compile with
-Wall -Wextraenabled 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 -O0to investigate a crash withgdb. - Producing an optimized
-O2release build of a performance-sensitive C++ application. - Compiling multi-threaded server or application code with
-pthreadto 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++.