/flags/cpp/gpp-pedantic-errors
g++ -pedantic-errors and -Wpedantic: reject non-standard C++ extensions
- tool
- C++
- command
- g++
- flag
- -pedantic-errors, -Wpedantic (-pedantic)
- default
- off: GCC and Clang accept their extensions, sometimes with a warning
g++ -std=c++17 -pedantic-errors main.cpp makes the compiler reject code that the ISO C++ standard does not allow but GCC or Clang accept as an extension: variable-length arrays, designated initializers before C++20, zero-size arrays, __int128 and similar. -Wpedantic (also spelled -pedantic) reports the same issues as warnings. Use them to keep code portable to MSVC and other compilers.
Extensions accepted by default
The example uses Clang 20 from the Zig 0.15.1 toolchain (installed from PyPI with uv); cxx below is that compiler, and g++ accepts the same options:
cxx() { uv run -q --no-project --python 3.13 --with ziglang==0.15.1 python -m ziglang c++ -fno-color-diagnostics "$@"; }
cat > ext.cpp <<'EOF'
#include <cstdio>
int main(int argc, char**) {
int n = argc + 2;
int vla[n]; // variable-length array: not C++
vla[0] = 1;
struct P { int x, y; } p = { .x = 1, .y = 2 }; // designated initializers: C++20
std::printf("%d %d\n", vla[0], p.y);
}
EOF
show() { cxx "$@" ext.cpp -o ext 2>&1 | grep -E '(warning|error):'; echo "exit: ${PIPESTATUS[0]}"; }
echo "== -std=c++17"
show -std=c++17
echo "== -std=c++17 -Wpedantic"
show -std=c++17 -Wpedantic
echo "== -std=c++17 -pedantic-errors"
show -std=c++17 -pedantic-errors
echo "== -std=c++20 -pedantic-errors"
show -std=c++20 -pedantic-errorsOutput
== -std=c++17 ext.cpp:4:13: warning: variable length arrays in C++ are a Clang extension [-Wvla-cxx-extension] exit: 0 == -std=c++17 -Wpedantic ext.cpp:4:13: warning: variable length arrays in C++ are a Clang extension [-Wvla-cxx-extension] ext.cpp:6:34: warning: designated initializers are a C++20 extension [-Wc++20-designator] exit: 0 == -std=c++17 -pedantic-errors ext.cpp:4:13: error: variable length arrays in C++ are a Clang extension [-Werror,-Wvla-cxx-extension] ext.cpp:6:34: error: designated initializers are a C++20 extension [-Werror,-Wc++20-designator] exit: 1 == -std=c++20 -pedantic-errors ext.cpp:4:13: error: variable length arrays in C++ are a Clang extension [-Werror,-Wvla-cxx-extension] exit: 1
Plain -std=c++17 builds the program and warns only about the VLA (Clang has that warning on by default; GCC accepts VLAs silently). -Wpedantic adds the designated-initializer warning; -pedantic-errors turns both into errors and the build fails. With -std=c++20 designated initializers are standard, so only the VLA remains.
The three levels
| Options | Extensions | Build result |
|---|---|---|
| (none) | Accepted; a few produce warnings | Succeeds |
| -Wpedantic / -pedantic | Every standard-required diagnostic is a warning | Succeeds |
| -pedantic-errors | Standard-required diagnostics are errors | Fails on extensions |
| -Wpedantic -Werror | All warnings, pedantic or not, are errors | Fails on any warning |
| -Wno-vla / -Wno-error=vla | Opt out of one diagnostic | Selective exceptions |
Common extensions it catches
| Code | Why it is non-standard | Portable alternative |
|---|---|---|
| int a[n]; with runtime n | VLAs are C99, not C++ | std::vector<int> a(n); |
| { .x = 1 } before C++20 | Designated initializers arrived in C++20 | Positional init or -std=c++20 |
| int z[0]; | Zero-size arrays are not allowed | std::array or a flexible design |
| __int128 | Compiler-specific integer type | std::int64_t, or a big-integer library |
| Binary literal 0b1010 before C++14 | Standard only since C++14 | -std=c++14 or hex |
| Statement expressions ({ ... }) | GNU extension | A lambda called immediately |
Pitfalls
-pedantic-errorsfollows the-stdlevel: always pass an explicit-std=c++17(or newer, see -std=c++17), otherwise the compiler's default dialect decides what counts as an extension.- System and third-party headers can trigger pedantic diagnostics; include them with
-isystemso diagnostics in those headers are suppressed. - It is not a general warning switch: combine with -Wall -Wextra for bug-finding warnings.
-pedanticdoes not detect every non-portable construct, only those for which the standard requires a diagnostic; undefined behaviour is not reported.
FAQ
Is -pedantic-errors the same as -Wpedantic -Werror?
Not exactly. -pedantic-errors turns only the diagnostics required by the standard (the pedantic ones) into errors, while other warnings stay warnings. -Werror makes every enabled warning an error.
Why does MSVC accept code that g++ -pedantic-errors rejects?
Each compiler has its own extensions. MSVC has the /permissive- switch, the closest equivalent, which makes it follow the standard more strictly. Building with several compilers in CI catches most portability problems.
Should I use -std=gnu++17 or -std=c++17 with -pedantic?
Use -std=c++17 (no GNU extensions) together with -Wpedantic or -pedantic-errors when portability matters. With gnu++17 some extensions are allowed by the dialect, which defeats part of the purpose.