What is the difference between using -pedantic-errors and -Werror=pedantic in gcc?
Then (GCC 4.9) and now (GCC 12.2), the difference is that the latter option affects only diagnostics in the "pedantic" category, enabling them and causing them to be emitted as errors, whereas the former causes GCC to
Issue all the warnings demanded by strict ISO C[]; reject all programs that use forbidden extensions, and some other programs that do not follow ISO C
AND to
Give an error whenever the base standard (see -Wpedantic
) requires a diagnostic, [AND] in some cases where there is undefined behavior at compile-time [AND] in some other cases that do not prevent compilation of programs that are valid according to the standard.
In this context, it is important to understand under what circumstances the standard requires a diagnostic, which is specified in (C17 5.1.1.3/1):
A conforming implementation shall produce at least one diagnostic message [...] if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint [...]. Diagnostic messages need not be produced in other circumstances.
The term "constraint" is to be understood as any of the requirements explicitly called out as such by the spec. These are all of a nature that can be checked at compile time. You can think of them as adjuncts to the formal language syntax, refining the definition of what code is valid C at all. These are far fewer than the semantic rules specifying the meaning of C code that conforms to the syntax and constraints. Conformance to the requirements of syntactic rules cannot always be evaluated at compile time.
By default, GCC accepts some code that does not conform to C syntax and / or constraints without emitting a diagnostic. With the -pedantic
/ -Wpedantic
or -pedantic-errors
option in effect, it diagnoses most syntax and constraint violations relative to the selected dialect of the language. This is intended to provide a mode in which GCC is a conforming C processor, but it doesn't quite get there because there are several constraint violations that GCC does not diagnose even with these options.
With that settled, there are indeed some diagnostics that -pedantic-errors
will cause to be diagnosed as errors, but -Werror=pedantic
will not.
Example:
int y;
uintptr_t x = &y;
GCC accepts that code by default, even though C does not define the behavior of the assignment on account of there not being an implicit conversion from pointer to integer type. Older GCC does not even warn by default. When it does issue a diagnostic, it is something like this:
test_ped.c: In function ‘main’:
test_ped.c:6:19: warning: initialization of ‘uintptr_t’ {aka ‘long unsigned int’} from ‘int *’ makes integer from pointer without a cast [-Wint-conversion]
uintptr_t x = &y;
Note that the diagnostic category is int-conversion
. It should be no surprise, then, that compiling with -Werror=pedantic
does not cause this diagnostic to be emitted as an error. However, compiling with -pedantic-errors
does cause this diagnostic to be emitted as an error.
As far as I am aware, this is characteristic of the things for which -pedantic-errors
will emit errors but -Werror=pedantic
will not. They are all things that GCC diagnoses, when it diagnoses them at all, in a different category than "pedantic".
I have been unable to identify any examples of the converse, however -- diagnostics that only -Werror=pedantic
, not -pedantic-errors
, causes to be emitted as errors. But for the manual's explicit claim that such examples exist, I would not expect to find any, as the docs seem to say that -pedantic-errors
will cause a superset of the diagnostics in the pedantic
category to be emitted, as errors. I speculate that the manual may be out of date in that regard, if ever it was correct in the first place, but I am prepared to be surprised by an example.