C++ Module 1 – Start here: toolchains, compiling and first programs
Install a C++23 compiler on Windows, macOS or Linux
Set up Visual Studio, MSYS2, WSL, Apple clang, Homebrew GCC or your Linux packages, then confirm in two minutes that the toolchain really builds C++23.
What you will learn
- Install one supported C++ toolchain on your operating system and check its version
- Compile and run a test program with C++23 enabled
- Choose between MSVC, MSYS2 GCC and WSL on Windows
Before you start
What you’ll learn · Before you start
What you will learn
- Install one supported C++ toolchain on your operating system and check its version
- Compile and run a test program with C++23 enabled
- Choose between MSVC, MSYS2 GCC and WSL on Windows
Before you start
On this page
To write C++ you need a toolchain: a compiler, the standard library that comes with it, and a linker that joins the pieces into a program. Any of the three major compilers will do, GCC, Clang or Microsoft’s MSVC, if it is recent enough for C++23 and you ask for C++23 explicitly, because every compiler starts in an older edition by default.
The short version: on Windows, install Visual Studio for MSVC, MSYS2 for GCC, or a Linux system inside WSL; on macOS,
install Apple’s Command Line Tools and, if you want GCC as well, Homebrew’s gcc; on Linux, install your
distribution’s compiler packages and check their version. Then build one small test program. If it prints two lines,
your toolchain is ready for the lessons of this track.
Three ways to get C++ on Windows
Windows has no C++ compiler built in, and you have three good choices. All three are complete C++ toolchains; they differ in the tools around the compiler and in the kind of program they make.
| Option | Choose it when |
|---|---|
| Visual Studio (MSVC; builds Windows programs) | You want an IDE with a debugger, or you will write Windows desktop programs. Its options start with a slash, so its commands differ from this track’s. |
| MSYS2 (GCC; builds Windows programs) | You want GCC and Windows programs from a terminal, with the same commands as this track. |
| WSL 2 (GCC on Linux; builds Linux programs) | You want the Linux tools that servers and many contest judges use; the commands match this track exactly. |
If you are unsure, pick WSL 2, whose sessions will look exactly like the ones on these pages. Visual Studio is the better first choice if you prefer to click Build in an editor rather than type commands.
Visual Studio with MSVC
- Download Visual Studio Community from Microsoft’s Visual Studio site. Microsoft offers the Community edition to individual developers and for classroom learning, academic research and open-source work; for other uses it points to Visual Studio Professional or Enterprise, and the Community page states the exact terms.
- In the Visual Studio Installer, select the Desktop development with C++ workload and choose Install.
- Ask for C++23. In a project, open Properties › C/C++ › Language and set C++ Language Standard to
the C++23 preview or the latest working draft. On the command line, open Developer Command Prompt for VS from
the Start menu (a plain Command Prompt cannot find the compiler) and build with
cl /std:c++latest /EHsc /Zc:__cplusplus check_toolchain.cpp.
Each option in that command matters. MSVC compiles as C++14 when no /std option is given. /std:c++latest turns on
everything the compiler has implemented from C++23 and from the working draft after it, and Visual Studio 2022 version
17.13 and later also offer /std:c++23preview, which enables C++23 features only. /EHsc turns on standard C++
exception handling, which Microsoft recommends, and /Zc:__cplusplus makes the __cplusplus macro report the edition
instead of 199711L.
MSVC runs only on Windows, so the sessions on this page show GCC and Clang. If you want only the compiler without the IDE, Microsoft also publishes the Build Tools for Visual Studio.
MSYS2 with GCC
- Download the installer from msys2.org and run it; MSYS2 needs 64-bit Windows 10 (version 1809) or newer. Keep the default folder.
- When the installer finishes, it opens a terminal for the UCRT64 environment. In that terminal, install GCC
with
pacman -S mingw-w64-ucrt-x86_64-gccand confirm with Enter. - Check it with
g++ --version; MSYS2’s page shows its current build, GCC 16.2.0. Build the test program withg++ -std=c++23 check_toolchain.cpp -o check_toolchain.exeand run./check_toolchain.exe.
Use the UCRT64 terminal for C++ work. MSYS2 has several environments, and UCRT64 is the one that its getting-started page sets up with GCC.
WSL 2 with a Linux distribution
- Open PowerShell as administrator, run
wsl --installand restart the computer. It needs Windows 10 version 2004 (build 19041) or later, or Windows 11, and it installs Ubuntu unless you name another distribution with-d. - Start Ubuntu from the Start menu and create your Linux user name and password.
- Inside Ubuntu, follow the Linux steps below.
New distributions installed with wsl --install use WSL 2. The programs you build there are Linux programs, and the
commands are exactly the ones in this track.
macOS: Apple clang and Homebrew GCC
Apple’s compiler comes in the Command Line Tools package. Run xcode-select --install in Terminal and accept the
dialog; the tools install into /Library/Developer/CommandLineTools. If the full Xcode app is installed, you already
have them. clang++ --version should then report Apple clang.
One detail surprises many people: on a Mac, the command g++ is not GCC.
from session import run
# On a Mac, the command g++ is Apple clang; Homebrew's GCC is g++-16.
run("""
which g++
g++ --version | head -n 1
g++-16 --version | head -n 1
""") Output
$ which g++ /usr/bin/g++ $ g++ --version | head -n 1 Apple clang version 21.0.0 (clang-2100.3.34.2) $ g++-16 --version | head -n 1 g++-16 (Homebrew GCC 16.2.0) 16.2.0
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 macos_gpp_session.py
/usr/bin/g++ runs Apple clang, as its version line shows, with Apple’s libc++. To get the real GCC, install
Homebrew from brew.sh, follow the lines its installer prints for adding Homebrew to your PATH (Homebrew’s
documentation warns that it will not work otherwise), and run brew install gcc. The formula
installs GCC 16.2.0 with versioned names only, gcc-16 and g++-16, so it never hides Apple’s commands. On Apple
silicon, Homebrew lives in /opt/homebrew.
You do not need both compilers to follow this track. Apple clang alone is enough, and every page shows what each compiler prints, so you can compare your results with the one you have.
Linux: your distribution’s compiler packages
On Debian and Ubuntu, sudo apt install g++ installs the distribution’s default GCC; on Fedora, the package is
gcc-c++ (sudo dnf install gcc-c++). The version you get depends on the release, and long-term-support releases
keep the compiler they shipped with:
| Release | g++ |
Has std::print and std::ranges::to |
|---|---|---|
| Ubuntu 22.04 LTS | GCC 11 | No: install a newer GCC |
| Ubuntu 24.04 LTS | GCC 13 | No; the g++-14 package does |
| Ubuntu 26.04 LTS | GCC 15 | Yes |
| Debian 12 | GCC 12 | No: install a newer GCC |
| Debian 13 | GCC 14 | Yes |
| Fedora 43 | GCC 15 | Yes |
| Fedora 44 | GCC 16 | Yes |
The dividing line is GCC 14: it is the first GCC whose standard library has std::print and std::ranges::to, the
two C++23 features the test program uses. Ubuntu 24.04 also packages GCC 14, in its universe component:
sudo apt install g++-14 gives you a g++-14 command next to the default g++. Clang works on Linux too; whichever
compiler you choose, run the check below before you rely on it.
Check that your toolchain builds C++23
This program compiles only when three things are new enough: the compiler, its standard library and the edition you asked for. That makes it a quick health check for any toolchain.
// A health check for a C++23 toolchain: this file compiles only when the compiler,
// its standard library and the -std flag all support C++23.
#include <print>
#include <ranges>
#include <vector>
int main() {
// std::ranges::to, new in C++23, collects the first five squares into a vector.
auto squares = std::views::iota(1, 6)
| std::views::transform([](int n) { return n * n; })
| std::ranges::to<std::vector>();
std::print("Squares:");
for (int s : squares) {
std::print(" {}", s);
}
std::print("\n");
std::println("C++23 works here: __cplusplus is {}", __cplusplus);
} from session import run
run("""
clang++ --version | head -n 1
clang++ -std=c++23 check_toolchain.cpp -o check_toolchain && ./check_toolchain
g++-16 --version | head -n 1
g++-16 -std=c++23 check_toolchain.cpp -o check_toolchain && ./check_toolchain
file check_toolchain
""") Output
$ clang++ --version | head -n 1 Apple clang version 21.0.0 (clang-2100.3.34.2) $ clang++ -std=c++23 check_toolchain.cpp -o check_toolchain && ./check_toolchain Squares: 1 4 9 16 25 C++23 works here: __cplusplus is 202302 $ g++-16 --version | head -n 1 g++-16 (Homebrew GCC 16.2.0) 16.2.0 $ g++-16 -std=c++23 check_toolchain.cpp -o check_toolchain && ./check_toolchain Squares: 1 4 9 16 25 C++23 works here: __cplusplus is 202302 $ file check_toolchain check_toolchain: Mach-O 64-bit executable arm64
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 check_toolchain_session.py
Both toolchains print the same two lines, and __cplusplus confirms C++23 (202302). The last command, file, says
what was built: a native 64-bit program for Apple silicon. On Linux the same command reports an ELF executable, and on
Windows the program is an .exe file.
Why -std=c++23 matters
Every compiler picks an edition when you give no option, and none of them picks C++23. You can ask a compiler for its
default directly: -dM -E prints every predefined macro, and grep picks out __cplusplus.
from session import run
# Each compiler's default edition, then the health check built without -std=.
run("""
clang++ -dM -E -x c++ /dev/null | grep __cplusplus
g++-16 -dM -E -x c++ /dev/null | grep __cplusplus
clang++ check_toolchain.cpp -o check_toolchain
g++-16 check_toolchain.cpp -o check_toolchain
""", max_lines=3) Output
$ clang++ -dM -E -x c++ /dev/null | grep __cplusplus
#define __cplusplus 201402L
$ g++-16 -dM -E -x c++ /dev/null | grep __cplusplus
#define __cplusplus 202002L
$ clang++ check_toolchain.cpp -o check_toolchain
check_toolchain.cpp:9:25: error: no member named 'views' in namespace 'std'
9 | auto squares = std::views::iota(1, 6)
| ~~~~~^
[30 more lines]
[exit status 1]
$ g++-16 check_toolchain.cpp -o check_toolchain
check_toolchain.cpp: In function 'int main()':
check_toolchain.cpp:11:33: error: 'to' is not a member of 'std::ranges'
11 | | std::ranges::to<std::vector>();
[23 more lines]
[exit status 1]
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 default_standard_session.py
Apple clang 21 compiles as C++14 (201402) when you say nothing, older than upstream Clang, whose manual gives
gnu++17 as its default; GCC 16 moved its default to gnu++20; MSVC’s default is C++14. Without -std=c++23 the
check fails on both compilers, and their first errors look like missing names rather than an old edition: Clang
cannot find std::views, which arrived in C++20, and GCC cannot find std::ranges::to. So when a lesson’s example
fails with a “no member named” error, check the -std= option before anything else.
The gnu in gnu++20 means the GNU dialect: the standard plus a few compiler extensions. -std=c++23 asks for
standard C++23, and that is what this track uses everywhere.
When the check fails
| What you see | Why | What to do |
|---|---|---|
A “no member named” or “is not a member of” error for views or to |
No -std=c++23 (or /std:c++latest) on the command line |
Add the option and build again |
A “file not found” or “No such file or directory” error for <print> |
The standard library predates std::print: GCC before 14, or libc++ before 18 |
Install a newer compiler, such as g++-14 on Ubuntu 24.04 |
command not found: g++-16 on a Mac |
Homebrew’s folder is not on your PATH |
Run the PATH lines that Homebrew’s installer printed, then open a new terminal |
'cl' is not recognized as an internal or external command on Windows |
A plain Command Prompt, without the compiler’s settings | Use the Developer Command Prompt for VS |
MSVC prints __cplusplus is 199711 |
MSVC keeps the old value by default | Add /Zc:__cplusplus |
An undefined reference to std::print with a Windows build of GCC 14 |
GCC 14’s release notes say std::print needs an extra library on Windows |
Add -lstdc++exp to the link command |
Your turn
- Install one toolchain from this lesson, then save
check_toolchain.cppand build it with C++23 enabled. Your output should match the two lines in the session above. - Build it again without the edition option and note the first error. Then ask your compiler for its default with
-dM -E -x c++ /dev/null(GCC and Clang) and compare the value with the defaults described above. - If you have two compilers, build with both and check that the outputs agree.
Interview questions
Fresher · On a Mac, which compiler runs when you type g++, and how do you get GCC?
On macOS, /usr/bin/g++ runs Apple clang: g++ --version prints “Apple clang version …”, and the programs it builds
use Apple’s libc++ library. To get the real GCC, install it with Homebrew (brew install gcc), which adds versioned
commands such as g++-16 and leaves Apple’s g++ alone. A good answer adds why it matters: the two compilers have
different default editions, different warnings and different standard libraries, so the same code can behave
differently, and object files that pass standard-library types between them cannot be linked together.
Key takeaways
- A C++ toolchain is a compiler, its standard library and a linker; all three must be new enough for C++23.
- Windows: Visual Studio for MSVC, MSYS2’s UCRT64 environment for GCC, or WSL 2 for the Linux tools. macOS: the
Command Line Tools for Apple clang, Homebrew for
g++-16. Linux: the distribution’s packages, GCC 14 or newer. - No compiler starts in C++23: Apple clang 21 starts in C++14, GCC 16 in GNU C++20 and MSVC in C++14, so always ask
with
-std=c++23or/std:c++latest. check_toolchain.cppbuilds only when the compiler, the library and the edition all support C++23, which makes it a two-minute test for any new machine.
Check yourself
5 questions about this lesson. Every answer and why it is right is on the page, behind “Show the answer”. Your score stays in this browser.
References
- /std (Specify Language Standard Version) (Microsoft)
- /Zc:__cplusplus (Enable updated __cplusplus macro) (Microsoft)
- Install C and C++ support in Visual Studio (Microsoft)
- Walkthrough: Compiling a Native C++ Program on the Command Line (Microsoft)
- /EH (Exception handling model) (Microsoft)
- Microsoft C/C++ language conformance (Microsoft)
- Visual Studio Community (Microsoft)
- MSYS2 (getting started) (MSYS2 project)
- Install WSL (Microsoft)
- Technical Note TN2339: Building from the Command Line with Xcode FAQ (Apple)
- Homebrew installation (Homebrew)
- gcc (Homebrew formula) (Homebrew)
- clang (the Clang command guide) (LLVM Project)
- GCC 14 Release Series, Changes, New Features, and Fixes (GNU Project)
- GCC 16 Release Series, Changes, New Features, and Fixes (GNU Project)
- libc++ C++23 Status (LLVM Project)
- Ubuntu packages search for g++ (Canonical)
- g++-14 package in Ubuntu 24.04 (noble) (Canonical)
- Debian packages search for g++ (Debian Project)
- gcc-c++ (Fedora packages) (Fedora Project)
Related tools
Report a problem with this lesson
Kept only in this browser. Your Learn progress