Toolchain and first program

[toolchain]

Compile and run C++23 in your browser, format output with std::print, see why strings are values, and read the compiler's messages.

Lesson 1 of 10/5 checks passed

In this lesson you compile and run C++23 without installing anything, print formatted output with std::print, see why a C++ string behaves differently from one in C#, Java or Python, and practice reading the compiler’s messages. Each step ends with a check: compare your output with it, and tick it when they match.

Step 1: Set up Compiler Explorer

Compiler Explorer compiles and runs C++ in your browser, so you can start without a local toolchain. You will set one up in Lesson 10.

  1. Open godbolt.org. The left pane is the source editor; the right pane is a compiler.
  2. In the right pane’s compiler list, choose the newest x86-64 gcc (version 14 or later).
  3. Paste these into the Compiler options box next to it:
-std=c++23 -Wall -Wextra -O2
  • -std=c++23 turns on the C++23 language and library.
  • -Wall -Wextra turns on the warnings you will want throughout this course.
  • -O2 optimizes, as a release build would.

Finally, make the program run, not just compile: in the compiler pane, open Output and tick Execute the code, or add a pane with Add new… → Execution Only. The labels move a little between versions of the site; what you want is a pane that shows Program stdout.

Step 2: Your first C++23 program

Replace everything in the left editor with this program:

#include <print>
#include <string>

int main() {
    std::string name = "Ada";
    std::print("Hello, {}! __cplusplus = {}\n", name, __cplusplus);
}
  • #include <print> pastes the declarations from the <print> header into your file before compiling. It is not like C#’s using or Java’s import; Lesson 9 shows the modern replacement, import std;.
  • std:: is the standard library’s namespace, the way System. is in .NET.
  • std::print is new in C++23. The {} placeholders are filled in order, and the compiler checks that the arguments fit them.
  • main returns 0 automatically when it has no return statement.
  • __cplusplus is a number the compiler sets to the language version. For C++23 it is 202302.

Change "Ada" to your own name, then look at the program’s output.

Check 1.1 C++23 mode is on

The output reads Hello, <your name>! __cplusplus = 202302. A different number means -std=c++23 is missing from the compiler options or the compiler is older than GCC 14.

Step 3: Formatting output

std::println is std::print with a newline added. Inside the braces, a colon starts a format spec. If you know Python’s f-strings, this is the same mini-language; in C# terms, {:>8} plays the role of {0,8} and {:.2f} the role of {0:F2}.

#include <print>

int main() {
    std::println("[{:<8}]", "left");
    std::println("[{:>8}]", "right");
    std::println("[{:^8}]", "mid");
    std::println("{:.2f}", 3.14159);
    std::println("{} in hex is {:#x}", 255, 255);
    std::println("{1} comes before {0}", "second", "first");
}
  • <, > and ^ align left, right and center within the width that follows.
  • .2f prints a floating-point number with two decimals.
  • #x prints an integer in hexadecimal with a 0x prefix.
  • {1} and {0} pick arguments by position, so the same argument can be reused or reordered.
Check 1.2 Formatting matches

The output is exactly these six lines:

[left    ]
[   right]
[  mid   ]
3.14
255 in hex is 0xff
first comes before second

Step 4: Strings are values

In C#, Java and Python a string variable refers to a string object, and assigning it shares that object. In C++ a std::string variable is the string. Assigning it makes a separate copy you can change on its own.

#include <print>
#include <string>

int main() {
    std::string a = "one";
    std::string b = a;   // b gets its own copy of the characters
    b += "!";
    std::println("a = {}, b = {}", a, b);

    std::string& c = a;  // c is another name for a, not a copy
    c += "?";
    std::println("a = {}, c = {}", a, c);
}
  • b = a copies the characters, so appending to b leaves a alone.
  • std::string& c = a declares a reference: another name for a. Changing c changes a.
  • C++ makes copies unless you ask for a reference. That default is why later lessons care about when copies happen and how to avoid the expensive ones.
Check 1.3 Copies are independent

The output is exactly:

a = one, b = one!
a = one?, c = one?

Step 5: Reading warnings

A warning means the program compiled but something looks wrong. With -Wall -Wextra on, treat each warning as a bug report. Run this:

#include <print>

int main() {
    int total = 10;
    int unused = 5;
    std::println("total = {}", total);
}

The program still prints total = 10, and the compiler output pane (the Output button on the compiler pane) shows a warning. It names the file position as line:column and draws a ^ under the spot.

Check 1.4 Find the warning

The compiler output contains warning: unused variable 'unused' [-Wunused-variable] pointing at line 5. Delete line 5 and the warning disappears.

Step 6: Reading errors

An error stops the build. Replace the program with this one, which is missing a semicolon at the end of line 4:

#include <print>

int main() {
    int total = 10
    std::println("total = {}", total);
}

GCC reports:

<source>:5:5: error: expected ',' or ';' before 'std'
<source>:4:9: warning: unused variable 'total' [-Wunused-variable]

Two habits to take from this:

  • The error points where the compiler noticed, not always where the mistake is. GCC only realized the declaration was unfinished when it reached std on line 5, so look at the line before as well.
  • Fix the first error first. The unused-variable warning is a side effect: the broken line confused the compiler about the rest. Once line 4 is fixed, it goes away too.

Clang words it differently (expected ';' at end of declaration, on line 4). Both are right; they are describing the same mistake from different places.

Check 1.5 Fix the first error

You saw the error on line 5, added the ; at the end of line 4, and the program compiles with no errors or warnings and prints total = 10.

What you can do now

  • Compile and run C++23 in the browser with sensible warnings on.
  • Print and format output with std::print and std::println.
  • Explain why assigning a std::string copies it, and what a reference changes.
  • Read a compiler message: position, kind (warning or error), and why the first one matters most.

Next, Lesson 2 looks at how C++ decides types, what auto does and doesn’t do compared with C#’s var, and how const and constexpr let the compiler check and compute more for you.

Stuck on a check? Ask in the forum or see questions about this lesson.