Skip to content

/flags/cpp/gcc-std-cpp17

g++ -std=c++17: choose the C++ standard version

The commands on this page have not been executed by our verification runner yet.updated
tool
C++
command
g++
flag
-std=c++11|c++14|c++17|c++20|c++23 (or gnu++NN)
default
gnu++17 in GCC 11 and later; gnu++14 in GCC 6 to 10

g++ -std=c++17 compiles the code as ISO C++17; replace the number to pick another standard (c++11, c++14, c++20, c++23). Without the flag, GCC 11 and later use gnu++17 (C++17 plus GNU extensions). Use it when the compiler rejects newer features such as structured bindings, std::optional or concepts, for example with errors such as error: 'optional' in namespace 'std' does not name a template type. Clang accepts the same flag; MSVC uses /std:c++17.

Usage

bash
g++ -std=c++17 -Wall -Wextra -o app main.cpp
g++ -std=c++20 -o app main.cpp
clang++ -std=c++23 -o app main.cpp
g++ -std=gnu++17 -o app main.cpp         # C++17 with GNU extensions
echo | g++ -dM -E -x c++ - | grep __cplusplus   # default standard of this compiler

Values

Flag__cplusplusNotable features
-std=c++11201103Lauto, lambdas, move semantics, range-for
-std=c++14201402LGeneric lambdas, std::make_unique
-std=c++17201703LStructured bindings, std::optional, std::variant, if constexpr, std::filesystem
-std=c++20202002LConcepts, ranges, coroutines, std::format, modules
-std=c++23202302Lstd::expected, std::print, deducing this

The -std=c++2a, c++2b and c++2c spellings name standards that were not final yet in that compiler release; support for the newest standard is partial, so check the GCC and Clang status pages.

How to read the errors

When code needs a newer standard than the one in effect, the compiler rarely says so directly. The usual signs are:

  • A standard type is unknown, as in 'optional' in namespace 'std' does not name a template type or 'filesystem' is not a member of 'std' (see no member named in namespace std).
  • A language feature is reported as an extension or a syntax error, for example structured bindings or if constexpr on an older -std. GCC often adds a hint that the feature is only available with a later -std value.
  • A function is not found even though the header is included, because the declaration is guarded by a version check inside the library (see was not declared in this scope).

Check the default of the compiler you actually run with the __cplusplus command above; distribution packages and IDE toolchains can be older than you expect.

Other compilers

CompilerFlagNotes
GCC (g++)-std=c++17 or -std=gnu++17Default gnu++17 from GCC 11
Clang (clang++)-std=c++17 or -std=gnu++17Same spellings as GCC
MSVC (cl)/std:c++17/std:c++14 is the default; add /Zc:__cplusplus so the macro reports the real value

CMake

Set the standard on the target instead of adding the flag by hand:

cmake
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)      # -std=c++17 instead of -std=gnu++17

CMAKE_CXX_STANDARD_REQUIRED ON makes CMake fail at configure time when the compiler cannot do C++17, instead of silently falling back to an older standard. Setting the property per target with target_compile_features(app PUBLIC cxx_std_17) also passes the requirement on to targets that link against it.

FAQ

What is the difference between -std=c++17 and -std=gnu++17?

Both select C++17. The gnu++ form also enables GNU extensions and does not define __STRICT_ANSI__; the c++ form asks for ISO C++ and turns off extensions that conflict with the standard. Use c++17 for portable code.

Why does MSVC report __cplusplus as 199711L with /std:c++17?

For compatibility MSVC keeps the old value unless you also pass /Zc:__cplusplus. Code that checks the language version on MSVC should use that option or test _MSVC_LANG.

Can I use a newer -std than my standard library supports?

The flag only tells the compiler which language rules to apply. Library features such as std::format or std::print also need a standard library version that implements them, so check both the compiler and the library status pages.

Sources