Skip to content

/flags/cpp/gpp-pedantic-errors

g++ -pedantic-errors and -Wpedantic: reject non-standard C++ extensions

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
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:

bash
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-errors

Output

== -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

OptionsExtensionsBuild result
(none)Accepted; a few produce warningsSucceeds
-Wpedantic / -pedanticEvery standard-required diagnostic is a warningSucceeds
-pedantic-errorsStandard-required diagnostics are errorsFails on extensions
-Wpedantic -WerrorAll warnings, pedantic or not, are errorsFails on any warning
-Wno-vla / -Wno-error=vlaOpt out of one diagnosticSelective exceptions

Common extensions it catches

CodeWhy it is non-standardPortable alternative
int a[n]; with runtime nVLAs are C99, not C++std::vector<int> a(n);
{ .x = 1 } before C++20Designated initializers arrived in C++20Positional init or -std=c++20
int z[0];Zero-size arrays are not allowedstd::array or a flexible design
__int128Compiler-specific integer typestd::int64_t, or a big-integer library
Binary literal 0b1010 before C++14Standard only since C++14-std=c++14 or hex
Statement expressions ({ ... })GNU extensionA lambda called immediately

Pitfalls

  • -pedantic-errors follows the -std level: 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 -isystem so diagnostics in those headers are suppressed.
  • It is not a general warning switch: combine with -Wall -Wextra for bug-finding warnings.
  • -pedantic does 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.

Sources