Skip to content

/changelogs/cpp/cpp20-to-cpp23

C++20 to C++23: what changed in the language, tested with g++ -std=c++23

verified onenvironmentlocal · linux 6.18.44-fc-v236 x64 · GNU bash 5.2.21updated
tool
C++
versions
20 → 23

C++23 adds a handful of language features to C++20: a multidimensional operator[], static operator(), if consteval, auto(x), the #elifdef and #elifndef directives and "deducing this". GCC tracks them on its C++ status page and describes the C++23 support as experimental; the features arrive over several releases, so a feature that works in one GCC may be missing in an older one. Enable the standard with -std=c++23 (see __cplusplus values for how to detect it).

Language features

FeatureExampleUnder -std=c++20
Multidimensional subscriptint operator[](int r, int c) constError: operator[] must have exactly one argument
static operator()static int operator()(int a, int b)Warning that it needs -std=c++23
if constevalif consteval { ... } else { ... }Warning that it needs -std=c++23
auto(x)auto y = auto(x);Warning that it needs -std=c++23
#elifdef, #elifndef#elifdef NAMEPreprocessor shortcut for #elif defined(NAME)
Deducing thisint get(this const S& self)Needs a newer GCC than 13.3 even with -std=c++23
  • Multidimensional subscript. grid[1, 0] now calls operator[](int, int). In C++20 the comma in a subscript is deprecated, and GCC warns with -Wcomma-subscript.
  • static operator(). A function object with no state can have a static call operator, which avoids passing an unused this.
  • if consteval. Chooses a branch depending on whether the function is being evaluated at compile time. At run time the else branch runs.
  • auto(x). Makes a copy of x with decayed type, as a prvalue.
  • Deducing this. An explicit object parameter, written this const S& self, replaces overloads for const and non-const objects.

Test it with g++

bash
cat > t23.cpp <<'EOF'
struct Grid {
    int d[2][2] = {{1, 2}, {3, 4}};
    int operator[](int r, int c) const { return d[r][c]; }
};
struct Add { static int operator()(int a, int b) { return a + b; } };
constexpr int f() { if consteval { return 1; } else { return 2; } }
#ifdef FOO
#elifdef __cplusplus
#define KIND "elifdef"
#endif
int main() {
    Grid g; int x = 5;
    auto y = auto(x);
    return g[1, 0] + Add{}(2, 3) + f() + y + (KIND[0] == 'e');
}
EOF
g++ -std=c++23 -Wall t23.cpp -o t23 && echo "c++23 builds"
g++ -std=c++20 -Wall t23.cpp -o t20 2>&1 | grep "error:" | head -1

Output

c++23 builds
t23.cpp:3:9: error: ‘int Grid::operator[](int, int) const’ must have exactly one argument

The first command compiles the file as C++23. The second compiles it as C++20 and prints the first error: the two-argument operator[] is rejected.

Upgrade checklist

  1. Set -std=c++23 (or CMAKE_CXX_STANDARD 23) and read the new warnings.
  2. Search for [a, b] subscripts, which change meaning.
  3. Check each new feature against your compiler in the GCC status table before using it in shared code.
  4. Library features (such as std::expected) are tracked separately; test them with the feature macros from <version>.
  5. Compile errors about functions that no longer match are described in no matching function for call.

FAQ

How do I enable C++23 in g++?

Pass -std=c++23, or -std=gnu++23 to keep GNU extensions. The GCC status page says C++23 features are available since GCC 11. New features arrive release by release, so check the table for your version.

Is C++23 fully supported in GCC?

GCC describes its C++23 support as experimental and adds features over several releases. In a test with GCC 13.3, most language features below compiled, but deducing this was rejected. Check the GCC C++ status page for the release you use.

What does the code a[i, j] mean in C++23?

It calls a two-argument operator[] on the object. Before C++23 the comma was the comma operator and only the last value was used as the index. GCC warns about the old meaning under C++20 with -Wcomma-subscript.

Sources