g++ -std=c++17: choose the C++ standard version
- 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
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 compilerValues
| Flag | __cplusplus | Notable features |
|---|---|---|
| -std=c++11 | 201103L | auto, lambdas, move semantics, range-for |
| -std=c++14 | 201402L | Generic lambdas, std::make_unique |
| -std=c++17 | 201703L | Structured bindings, std::optional, std::variant, if constexpr, std::filesystem |
| -std=c++20 | 202002L | Concepts, ranges, coroutines, std::format, modules |
| -std=c++23 | 202302L | std::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 typeor'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 constexpron an older-std. GCC often adds a hint that the feature is only available with a later-stdvalue. - 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
| Compiler | Flag | Notes |
|---|---|---|
| GCC (g++) | -std=c++17 or -std=gnu++17 | Default gnu++17 from GCC 11 |
| Clang (clang++) | -std=c++17 or -std=gnu++17 | Same 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:
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) # -std=c++17 instead of -std=gnu++17CMAKE_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
- gcc.gnu.orggcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html
- gcc.gnu.orggcc.gnu.org/projects/cxx-status.html
- clang.llvm.orgclang.llvm.org/cxx_status.html
- cmake.orgcmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html
- learn.microsoft.comlearn.microsoft.com/en-us/cpp/build/reference/std-specify-language-standard-version
- learn.microsoft.comlearn.microsoft.com/en-us/cpp/build/reference/zc-cplusplus