Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

C++  Module 1 – Start here: toolchains, compiling and first programs

What C++ is used for today and how to learn it

Where C++ runs today, from browsers and game engines to firmware and trading systems, what C++23 and C++26 mean, and how this track teaches the language.

  • Beginner
  • 15 minutes
  • Examples run with Clang 21.0.0, GCC 16.2.0 and Python 3.14.8
  • By MySmartCoPilot
Free: 15 minutes

What you will learn

  • Describe where C++ is used today, from browsers and game engines to firmware, finance and contests
  • Explain what "C++23 with C++26 previews" means for the code in this track
  • Reproduce a recorded output on the page with the commands shown in its session
What you’ll learn

What you will learn

  • Describe where C++ is used today, from browsers and game engines to firmware, finance and contests
  • Explain what "C++23 with C++26 previews" means for the code in this track
  • Reproduce a recorded output on the page with the commands shown in its session
On this page

C++ is a compiled, general-purpose programming language for software that has to be fast, predictable and close to the hardware. It runs inside web browsers and compilers, game engines, the firmware of small devices, trading and banking systems, and the engines underneath data and machine-learning libraries. You decide how data is laid out in memory, no garbage collector ever pauses the program, and C libraries can be called directly, which is why so many long-lived systems are written in it. It is also one of the languages that programming contests accept.

The price is responsibility. A C++ compiler trusts the programmer, and a mistake with memory can corrupt a program without any error message. This track teaches modern C++, the style that avoids most of those mistakes, and builds every example with two compilers, so you can see exactly what each one does with your code.

Where C++ runs today

C++ is most at home in large programs that live for years and need speed. Here are six areas, each described from the project’s own documentation:

  • Browsers and compilers. Chromium, the open-source browser project, has a C++ style guide that targets C++23. The LLVM project, home of the Clang compiler, is written in standard C++17, and building GCC requires a C++14 compiler, because GCC itself is written in C++.
  • Game engines. In Unreal Engine you write gameplay classes in C++ and compile them with Visual Studio or Xcode; the editor then picks up the changes.
  • Embedded devices. The Zephyr real-time operating system runs C++ applications on microcontrollers with a reduced feature set: exceptions stay off until you turn them on, and there is no std::thread.
  • Finance. Bloomberg publishes BDE, the foundational C++ libraries it uses, as an open-source project.
  • Data and machine learning. PyTorch describes ATen, its C++ tensor library, as the base on which almost all of its Python and C++ interfaces are built. When you call PyTorch from Python, the tensor operations run in that library.
  • Programming contests. The ICPC World Finals accept C, C++, Java, Kotlin and Python, and compile C++ with GCC 13.2.0 using -std=gnu++20 -O2. Online judges each have their own compiler and flags, which a later module of this track compares.

What these have in common: the code runs for a long time, on many machines or on small ones, so every millisecond and every kilobyte counts, and much of it is far too large to rewrite in another language.

Why people choose C++, and what it costs

Three properties explain most of the list above.

  • Control. You choose whether an object lives on the stack or on the heap and how its fields are arranged in memory, and objects are destroyed at a known point, so the program’s timing does not depend on a garbage collector.
  • Generic code that stays fast. A template such as the standard library’s std::sort is compiled separately for each type you use it with, so a general-purpose function can be as specific as code written by hand for one type.
  • Compatibility. C++ calls C functions directly and can offer a C interface to other languages, and most code written for an older standard still compiles under a newer one.

The cost is memory safety. The Chromium project reports that around 70 % of its high-severity security bugs are memory-safety problems, mistakes with C and C++ pointers, in an analysis of 912 high and critical bugs. Modern C++ lowers that risk rather than removing it: containers such as std::vector and std::string manage their own memory, smart pointers release what they own, and compiler warnings and sanitizers catch many mistakes while you test. C++26 goes further. It adds a standard library that can check bounds on common operations, and reading an uninitialised local variable stops being undefined behaviour.

C++ is also big. The C++23 working draft, N4950, is 2,134 pages long, and the C++26 final draft, N5050, has 2,679 pages. Nobody needs all of it: this track teaches the parts that everyday code uses and says where the rest lives.

What “C++23 with C++26 previews” means

C++ is defined by an international standard, ISO/IEC 14882, which is revised every three years. Each edition is named after the year its technical work was finished: C++11, C++14, C++17, C++20 and C++23. The current edition is C++23, formally ISO/IEC 14882:2024; the later year in the formal name is when ISO published the document.

C++26 is finished but not yet published. The ISO C++ committee completed its technical work at its meeting in London (Croydon), and N5050, the final draft, is the basis of the Draft International Standard, the document that the national standards bodies vote on. Compilers already implement parts of it: Clang accepts -std=c++2c, and GCC 16 adds reflection (with -std=c++26 -freflection) and contracts.

This track writes C++23. A lesson that uses a C++26 feature says so and names the compilers that support it, and the C++26 module marks every feature in it as a preview.

A program can ask which edition it is compiled for. The predefined macro __cplusplus holds a number made of the year and the month of the edition:

standard_version.cpp: print the edition C++ · standard_version.cpp
// Prints which edition of the C++ standard the compiler was told to follow.
#include <iostream>

int main() {
    std::cout << "__cplusplus = " << __cplusplus << "L\n";
}

Below, that file is built for four editions with each compiler. A line that starts with $ is a command, and the lines under it are what the command printed:

Four editions, two compilers Python · standard_version_session.py
from session import run

run("""
clang++ --version | head -n 1
clang++ -std=c++17 standard_version.cpp -o standard_version && ./standard_version
clang++ -std=c++20 standard_version.cpp -o standard_version && ./standard_version
clang++ -std=c++23 standard_version.cpp -o standard_version && ./standard_version
clang++ -std=c++2c standard_version.cpp -o standard_version && ./standard_version
g++-16 --version | head -n 1
g++-16 -std=c++17 standard_version.cpp -o standard_version && ./standard_version
g++-16 -std=c++20 standard_version.cpp -o standard_version && ./standard_version
g++-16 -std=c++23 standard_version.cpp -o standard_version && ./standard_version
g++-16 -std=c++2c standard_version.cpp -o standard_version && ./standard_version
""")

Output

$ clang++ --version | head -n 1
Apple clang version 21.0.0 (clang-2100.3.34.2)
$ clang++ -std=c++17 standard_version.cpp -o standard_version && ./standard_version
__cplusplus = 201703L
$ clang++ -std=c++20 standard_version.cpp -o standard_version && ./standard_version
__cplusplus = 202002L
$ clang++ -std=c++23 standard_version.cpp -o standard_version && ./standard_version
__cplusplus = 202302L
$ clang++ -std=c++2c standard_version.cpp -o standard_version && ./standard_version
__cplusplus = 202400L
$ g++-16 --version | head -n 1
g++-16 (Homebrew GCC 16.2.0) 16.2.0
$ g++-16 -std=c++17 standard_version.cpp -o standard_version && ./standard_version
__cplusplus = 201703L
$ g++-16 -std=c++20 standard_version.cpp -o standard_version && ./standard_version
__cplusplus = 202002L
$ g++-16 -std=c++23 standard_version.cpp -o standard_version && ./standard_version
__cplusplus = 202302L
$ g++-16 -std=c++2c standard_version.cpp -o standard_version && ./standard_version
__cplusplus = 202400L

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 standard_version_session.py

The two compilers agree: 201703 for C++17, 202002 for C++20 and 202302 for C++23. For the unfinished C++26 both print 202400, a provisional value that is simply larger than C++23’s. The final draft sets 202603, and compilers move to it as they complete C++26. The -std= option chooses the edition; without it each compiler picks a default of its own, which the next lesson measures.

Which compiler made this output?

Every compiler announces itself through predefined macros, and the standard library adds its own in the <version> header. This program reports both:

which_compiler.cpp: identify the toolchain C++ · which_compiler.cpp
// Prints which compiler and which standard library built this program.
#include <iostream>
#include <version>  // the standard library's version macros

int main() {
#if defined(__clang__)  // test Clang first: it also defines __GNUC__
    std::cout << "compiler: Clang " << __clang_major__ << '.' << __clang_minor__ << '.'
              << __clang_patchlevel__ << '\n';
#elif defined(__GNUC__)
    std::cout << "compiler: GCC " << __GNUC__ << '.' << __GNUC_MINOR__ << '.' << __GNUC_PATCHLEVEL__ << '\n';
#elif defined(_MSC_VER)
    std::cout << "compiler: MSVC " << _MSC_VER << '\n';
#endif

#if defined(__GNUC__)
    std::cout << "__GNUC__: " << __GNUC__ << '\n';
#endif

#if defined(_LIBCPP_VERSION)
    std::cout << "library:  libc++ " << _LIBCPP_VERSION << '\n';
#elif defined(_GLIBCXX_RELEASE)
    std::cout << "library:  libstdc++ of GCC " << _GLIBCXX_RELEASE << '\n';
#endif

    std::cout << "standard: " << __cplusplus << "L\n";
}
The same file, two toolchains Python · which_compiler_session.py
from session import run

run("""
clang++ -std=c++23 which_compiler.cpp -o which_compiler && ./which_compiler
g++-16 -std=c++23 which_compiler.cpp -o which_compiler && ./which_compiler
""")

Output

$ clang++ -std=c++23 which_compiler.cpp -o which_compiler && ./which_compiler
compiler: Clang 21.0.0
__GNUC__: 4
library:  libc++ 220106
standard: 202302L
$ g++-16 -std=c++23 which_compiler.cpp -o which_compiler && ./which_compiler
compiler: GCC 16.2.0
__GNUC__: 16
library:  libstdc++ of GCC 16
standard: 202302L

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 which_compiler_session.py

Three details in that output are worth knowing:

  • A toolchain is a compiler plus a standard library. Apple clang ships with libc++, the LLVM project’s library, and GCC ships with libstdc++. The number 220106 packs libc++’s version into two digits each for major, minor and patch, so it means 22.1.6.
  • Clang also defines __GNUC__. It reports 4, so code that tests __GNUC__ alone mistakes Clang for a very old GCC. That is why the program checks __clang__ first.
  • MSVC needs an option. Microsoft’s compiler keeps __cplusplus at 199711L unless you compile with /Zc:__cplusplus, because a lot of existing code depends on the old value. Its own _MSC_VER macro gives the compiler version.

How to read the examples in this track

Each example shows the C++ file first and then a terminal session that builds and runs it: the commands after $, then what they printed. The sessions were run on a Mac with Apple silicon (macOS 26) with Apple clang 21.0.0 and GCC 16.2.0. When the two compilers print different things, both results are shown.

Old code that no longer compiles

New editions occasionally remove things. std::auto_ptr was the standard smart pointer before C++11; it was deprecated when std::unique_ptr replaced it and removed from the standard in C++17. Code in older tutorials still uses it:

old_auto_ptr.cpp: code from an older tutorial C++ · old_auto_ptr.cpp
// Code in the style of an old tutorial: std::auto_ptr was the standard smart pointer before C++11.
#include <iostream>
#include <memory>

int main() {
    std::auto_ptr<int> score(new int(42));
    std::cout << "score = " << *score << '\n';
}
Accepted by one library, rejected by the other Python · old_auto_ptr_session.py
from session import run

# Only the first lines of each message are shown: they say what went wrong.
run("""
# Apple clang with its library, libc++
clang++ -std=c++23 old_auto_ptr.cpp -o old_auto_ptr_clang
# GCC with its library, libstdc++
g++-16 -std=c++23 old_auto_ptr.cpp -o old_auto_ptr_gcc
./old_auto_ptr_gcc
""", max_lines=4)

Output

# Apple clang with its library, libc++
$ clang++ -std=c++23 old_auto_ptr.cpp -o old_auto_ptr_clang
old_auto_ptr.cpp:6:10: error: no template named 'auto_ptr' in namespace 'std'; did you mean 'out_ptr'?
    6 |     std::auto_ptr<int> score(new int(42));
      |     ~~~~~^~~~~~~~
      |          out_ptr
[20 more lines]
[exit status 1]
# GCC with its library, libstdc++
$ g++-16 -std=c++23 old_auto_ptr.cpp -o old_auto_ptr_gcc
old_auto_ptr.cpp: In function 'int main()':
old_auto_ptr.cpp:6:10: warning: 'template<class> class std::auto_ptr' is deprecated: use 'std::unique_ptr' instead [-Wdeprecated-declarations]
    6 |     std::auto_ptr<int> score(new int(42));
      |          ^~~~~~~~
[5 more lines]
$ ./old_auto_ptr_gcc
score = 42

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 old_auto_ptr_session.py

Apple clang’s library follows the standard and no longer has std::auto_ptr, so the build fails. GCC’s library still provides it for old code and only warns, and its warning names the replacement, std::unique_ptr. So “it compiles on my machine” does not mean the code is valid C++23: the same file can build with one toolchain and fail with another. Two habits protect you. Learn from material written for C++17 or later, and read every warning: a deprecation warning names something that the standard has marked for removal, often with its replacement.

How to learn C++ with this track

The modules build on each other in this order:

  1. Toolchain and basics (this module): install a compiler, see how a program is built, read the compiler’s messages, and do console input and output.
  2. The core language: types and expressions, control flow, functions, vectors and other compound types, then references, pointers and memory.
  3. Classes and generic code: classes and RAII (resources tied to object lifetimes), inheritance, templates and concepts.
  4. The standard library in depth: containers, iterators, algorithms and ranges, move semantics and smart pointers, error handling, and input and output.
  5. Engineering: build systems and tools, concurrency, modules and coroutines, and the C++26 previews.
  6. Where C++ is used: contests and DSA, systems programming, embedded devices, games, design, and interview practice.

A few habits make the language much easier to learn:

  • Build early and often. Compile after every few lines, so each error message points at something you just wrote.
  • Read the first error first. Later errors are often knock-on effects of the first one; a lesson of this module shows how to read them.
  • Prefer the standard library. Use std::vector and std::string long before raw arrays, and smart pointers instead of new and delete.
  • Type the examples yourself. Change a value, predict the output, then run it and compare with the session on the page.

Run the sessions yourself

Every session on these pages is a short Python file that hands each command to /bin/sh and prints it after $, together with what it printed. The work is done by session.py, shown below; save it in the same folder as a lesson’s files to repeat a session on macOS or Linux with python3 standard_version_session.py. You can equally type the commands one by one: that is all the script does.

session.py: runs the commands of a session Python · session.py
"""Runs shell commands the way you would type them in a terminal, and prints the session.

Each line of a script is one command. The session shows it after "$ ", then what it printed, with standard output
and standard error together, as a terminal shows them. A command that fails adds a line with its exit status, and
the session goes on with the next command. A line that starts with "#" is printed as a comment.
"""

import os
import subprocess

# Homebrew's folders of commands (Apple silicon, then Intel Macs): the gcc formula puts g++-16 there.
HOMEBREW_BIN = ["/opt/homebrew/bin", "/usr/local/bin"]


def run(script: str, max_lines: int = 30) -> None:
    """Runs each line of `script` with /bin/sh and prints at most `max_lines` lines of what each command printed."""
    env = dict(os.environ)
    env["PATH"] = os.pathsep.join([env.get("PATH", ""), *HOMEBREW_BIN])
    for command in script.strip().splitlines():
        command = command.strip()
        if not command or command.startswith("#"):
            print(command)
            continue
        print(f"$ {command}")
        result = subprocess.run(command, shell=True, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
        lines = result.stdout.splitlines()
        for line in lines[:max_lines]:
            print(line)
        if len(lines) > max_lines:
            print(f"[{len(lines) - max_lines} more lines]")
        if result.returncode != 0:
            print(f"[exit status {result.returncode}]")

Interview questions

Fresher · What does __cplusplus tell you, and which values mean C++17, C++20 and C++23?

__cplusplus is a macro that every C++ compiler defines. Its value says which edition of the standard the compiler is following, written as a year and a month: 201703L for C++17, 202002L for C++20 and 202302L for C++23, so code can test #if __cplusplus >= 202002L. Two cautions make the answer complete. Microsoft’s compiler reports 199711L unless you compile with /Zc:__cplusplus, and editions still in draft use provisional values (Clang and GCC print 202400L for -std=c++2c). To check for one feature, a feature-test macro such as __cpp_lib_print from <version> is more precise than the edition number.

Key takeaways

  • C++ runs where speed, predictable timing and control over memory matter: browsers and compilers, game engines, embedded devices, finance, data and machine-learning libraries, and programming contests.
  • The price of that control is memory safety; modern C++ (containers, smart pointers, warnings, sanitizers) and the C++26 hardening features reduce the risk.
  • C++23, formally ISO/IEC 14882:2024, is the current standard. C++26 is technically finished but not yet published, and this track marks every C++26 feature as a preview.
  • __cplusplus tells you the edition a file was compiled for; -std= chooses it.
  • A toolchain is a compiler and a standard library, and two toolchains can disagree about the same file, as std::auto_ptr shows.

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.

  1. Question 1 of 5 In the session "Four editions, two compilers", which number does standard_version.cpp print for __cplusplus when it is built with -std=c++20? Leave out the L.

    Type a number.

    Show the answer to question 1

    Answer: 202002

    The value is the year and month of the edition: 202002 for C++20. Both Apple clang 21 and GCC 16 print the same number, as they do for C++17 (201703) and C++23 (202302).

  2. Question 2 of 5 For -std=c++2c, both compilers print the same provisional value for the unfinished C++26. What is it? Leave out the L.

    Type a number.

    Show the answer to question 2

    Answer: 202400

    Both print 202400, a placeholder that is larger than C++23's 202302. The final C++26 draft, N5050, sets 202603, and compilers move to that value as they complete C++26.

  3. Question 3 of 5 What is the formal name of the C++23 standard?

    Choose one answer.

    Show the answer to question 3

    Answer: ISO/IEC 14882:2024

    C++ is ISO/IEC 14882. The edition is named after the year its technical work was finished (2023), and the formal name carries the year ISO published it (2024). ISO/IEC 9899 is the C standard, and N4950 is a working draft.

  4. Question 4 of 5 What happened when old_auto_ptr.cpp, which uses std::auto_ptr, was built with -std=c++23?

    Choose one answer.

    Show the answer to question 4

    Answer: Apple clang rejected it; GCC 16 built it with a deprecation warning, and the program ran

    The standard removed std::auto_ptr in C++17. Apple clang's library, libc++, follows the removal, while GCC's libstdc++ still provides the class for old code and warns that it is deprecated, naming std::unique_ptr as the replacement.

  5. Question 5 of 5 This code is built with Apple clang 21. What does it print?

    Read the code, then choose one answer.

    #if defined(__GNUC__)
        std::cout << "GCC\n";
    #elif defined(__clang__)
        std::cout << "Clang\n";
    #endif
    Show the answer to question 5

    Answer: GCC

    Clang also defines __GNUC__ (it reports 4) for code that tests for GCC, so the first branch wins. Test __clang__ first, as which_compiler.cpp does.

References

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.