Installing a C++ compiler on Windows, Linux and macOS comes down to one idea: every platform ships a way to add a compiler to your PATH, and once the compiler answers on the command line you can build any C++ program. Linux gives you the whole toolchain in a single package, macOS gives it to you through Xcode command line tools, and Windows lets you choose between the Microsoft toolchain and a Unix-like one that behaves identically on every platform.
Installing a C++ compiler on Windows, Linux and macOS at a glance
Before the per-platform details it helps to know the shape of the answer. A C++ compiler is a program called g++, clang++ or cl.exe that reads a source file and writes an executable. It is not part of Windows, macOS or Linux by default, which is why a fresh laptop usually answers "command not found" the first time you try it. Every fix below ends with the same two steps: install the toolchain, then confirm the terminal can find it.
The three mainstream choices are worth distinguishing up front.
- GNU Compiler Collection (g++) — the default on most Linux distributions, available on macOS through Homebrew or the Xcode tools, and available on Windows through MSYS2 or WSL. Very standard library support, and the compiler most online tutorials assume.
- LLVM/Clang (clang++) — the default on Apple platforms. Faster diagnostics, stricter warnings, and increasingly the compiler of choice for new projects. The C++ standard library it ships with is usually the same GNU one.
- Microsoft Visual C++ (cl.exe) — ships with Visual Studio on Windows and is the only option guaranteed to produce binaries that plug into the Microsoft toolchain directly. It is stricter about some extensions than g++.
For learning C++ from scratch, pick one and stay with it. Most tutorials, most compilers and most compiler flags translate almost one-to-one between them, and switching toolchains later costs far more time than it saves now.
Installing a C++ compiler on Windows
Windows has three reasonable routes, and they are not equally painful. The Visual Studio route is the most integrated: download the Community edition, run the installer, and tick the workload called "Desktop development with C++". That single tick installs the MSVC compiler, the Windows SDK, the debugger and an editor, and sets up the environment for you.
The route that most closely matches a Linux or macOS course is MSYS2. It gives you a Unix-like shell, a package manager called pacman, and a current g++.
# Windows: install MSYS2 from the official installer, then run this in the MSYS2 UCRT64 shell
pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain
# confirm the toolchain landed on the PATH
g++ --version
clang++ --versionThe third route is the Windows Subsystem for Linux. If you already use WSL, install the build tools inside your Linux distribution and never think about Windows compilers again. The catch is that your source files live inside the WSL filesystem, and editing them from a Windows editor over a network share is workable but noticeably slower.
If you want the shortest possible path to a working compiler on Windows and do not care which one it is, Visual Studio is the answer. If you want the compiler your course assumes, install MSYS2 or use WSL.
Installing a C++ compiler on macOS
macOS is the easiest of the three. Xcode command line tools contain the Clang compiler and the standard library, and installing them needs one command from a terminal.
# macOS: install the Xcode command line tools (Apple's compiler, clang++)
xcode-select --install
# confirm
clang++ --versionIf the dialog that appears asks for permission, accept it; the download is a few hundred megabytes and takes a few minutes. If you would rather have GNU g++ on macOS, Homebrew installs it in seconds and links it as g++ alongside the Apple compiler.
# macOS: install GNU g++ through Homebrew as well
brew install gcc
brew install --c++ gcc
g++-13 --versionHomebrew deliberately does not overwrite the Apple compiler, so your existing projects keep building exactly as before. That is a feature: you can keep both and choose per project.
Installing a C++ compiler on Linux
Linux distributions ship a C++ compiler in their package repository. The exact package name differs, but the shape of the command is identical everywhere.
# Debian, Ubuntu, Mint
sudo apt update
sudo apt install build-essential
# Fedora, RHEL, CentOS Stream
sudo dnf install gcc gcc-c++ make
# Arch, Manjaro
sudo pacman -S base-develThe package usually installs several tools at once: the C compiler gcc, the C++ compiler g++, the linker, the archiver and make. You want all of them, because a C++ program needs more than a compiler — it needs a linker to combine your code with the standard library.
On a minimal container image, the same idea applies. A Debian slim image needs the same build-essential package; a Fedora image needs the gcc-c++ one.
# inside a minimal container
apt-get update && apt-get install -y build-essential
g++ --versionVerifying the installation
Verification has two halves, and beginners routinely check only the first. Ask the compiler for its version, then ask it to build and run something trivial.
# 1. which compiler, and which version
g++ --versionThe second half is a real program, compiled and run in one step so that a failed compile can never be mistaken for a successful run.
#include
int main() {
std::cout << "the toolchain works\n";
return 0;
}g++ -std=c++17 -Wall -Wextra hello.cpp -o hello && ./helloA missing header is a compile problem, an is a link problem, and a missing shared library is a runtime problem, so the message names the stage that failed.undefined reference
A healthy Linux box prints something close to this:
g++ (Debian 12.2.0-14) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.The build step should print nothing at all and the exit code should be zero. Silence from a compiler is success; any output at all means it had something to say, usually a warning or an error.
The compiled program above is the real proof, because it exercises the full chain: the preprocessor, the compiler proper, the assembler and the linker.
What to do when the compiler is not found
If the shell reports that g++ is not recognised, the binary exists somewhere but is not on the PATH. Find out where it lives first, then decide whether to move the PATH or move the binary.
# Linux and macOS: is it installed but not on the PATH?
ls /usr/bin/g++* /usr/local/bin/g++* 2>/dev/null
which -a g++
# Windows (PowerShell)
where.exe g++
Get-Command g++ -ErrorAction SilentlyContinueIf the compiler is installed under a path such as /usr/local/bin, add that directory to your PATH permanently rather than exporting it per shell session.
# Linux and macOS: make the change stick
echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrcOn Windows, the equivalent is the System Properties dialog: open Environment Variables, add the compiler's bin folder to the user PATH, and open a brand new terminal afterwards. The new-window step is not optional, because already-open terminals keep the old PATH they were started with.
Which language standard should you compile with?
Modern C++ is versioned, and the standard flag is how you tell the compiler which version of the language to accept. Compile with C++17 or later for anything you write today.
g++ -std=c++17 -Wall -Wextra -O2 main.cpp -o programThe flags in that command are worth understanding even at this stage. -std=c++17 selects the language version. -Wall turns on the common warnings, -Wextra adds more, and -O2 asks for optimised machine code. Any one of them can be dropped, but you should never ship code compiled without at least -Wall.
Checking what the compiler supports
The version string tells you which compiler you have; a small program tells you which language features it accepts. The __cplusplus macro expands to a number describing the standard in use.
#include
int main() {
std::cout << "__cplusplus: " << __cplusplus << "\n";
#if __cplusplus >= 201703L
std::cout << "C++17 or later is available\n";
#else
std::cout << "this compiler defaults to an older standard\n";
#endif
return 0;
}The output on a modern compiler reads:
__cplusplus: 201703
C++17 or later is availableThe #if directive is a preprocessor conditional, and it works in every part of a C++ file. Because the standard is known before compilation begins, a compiler can even be asked to reject code that uses a newer feature.
Quick reference
- Windows: Visual Studio with the C++ workload, MSYS2 with pacman, or WSL with build-essential — all three work.
- macOS:
xcode-select --installgives you clang++; Homebrew adds GNU g++ alongside it. - Linux: one package (
build-essentialon Debian family,gcc-c++on Fedora family) gives you the compiler, the linker and make. - Verify with a real build, not just
--version: compile a trivial program and check the exit code. - If the command is not found, the compiler is installed but not on the PATH; find it, then fix the PATH.
- Compile with
-std=c++17and-Wall -Wextrafrom your very first project so warnings surface early.
Building something a little larger
Once the smoke test works, the next step is a program that does real work.
#include
#include
double to_fahrenheit(double celsius) {
return celsius * 9.0 / 5.0 + 32.0;
}
int main() {
std::cout << "21.5C is " << to_fahrenheit(21.5) << "F\n";
return 0;
}The output confirms the arithmetic:
21.5C is 70.7FTry it yourself: install a compiler using the route for your platform, then run the three-step verification: print the version, compile the smoke test, and run it. Next, deliberately break the PATH for a single shell session, confirm the "command not found" message, restore it, and note which folder on your machine actually holds the compiler binary.