-std=c90 -pedantic-errors and <stdint.h>

David Brown david@westcontrol.com
Thu Jun 1 12:22:00 GMT 2017

On 01/06/17 13:52, Vincent Lefevre wrote:
> On 2017-06-01 13:14:50 +0200, David Brown wrote:
>> On 31/05/17 01:23, Vincent Lefevre wrote:
>>> On 2017-05-30 23:04:02 +0200, Florian Weimer wrote:
>>>> * Vincent Lefevre:
>>>>> Is it normal that -std=c90 -pedantic-errors allows to use
>>>>> #include <stdint.h>
>>>>> ?
>>>> Yes.  It's difficult where to draw the line.  <inttypes.h> was
>>>> apparently available with some C90 compilers, so it would make sense
>>>> to allow it in C90 mode.  But this means that it wouldn't be
>>>> completely out of line to accept <stdint.h>, too.
>> I have used C90 compilers that provided a <stdint.h> too.
>> And since C90 does not define a <stdint.h>, an implementation or user is
>> free to put a file called "stdint.h" in a directory that is searched for
>> system includes - a compiler cannot arbitrarily blacklist a header name
>> in a standard that does not mention that name!
> Note that with -pedantic-errors, this is more than a compiler,
> there are also strong compatibility tests. Without -pedantic-errors,
> <stdint.h> would *not* be blacklisted. Ditto if the user uses some
> -Wno- option to disable the associated warning.

The compiler cannot blacklist <stdint.h> in pedantic C90 mode without
breaking C90 compatibility.  The C90 standards say nothing about
<stdint.h> - it is therefore just as legitimate a header name as <foo.h>
would be.  The compiler cannot retroactively reserve file names from
future standards in the way you suggest.

> If you want an example:
>   -Woverlength-strings
>       Warn about string constants that are longer than the "minimum
>       maximum" length specified in the C standard.  Modern compilers
>       generally allow string constants that are much longer than the
>       standard's minimum limit, but very portable programs should avoid
>       using longer strings.
>       The limit applies after string constant concatenation, and does not
>       count the trailing NUL.  In C90, the limit was 509 characters; in
>       C99, it was raised to 4095.  C++98 does not specify a normative
>       minimum maximum, so we do not diagnose overlength strings in C++.
>       This option is implied by -Wpedantic, and can be disabled with
>       -Wno-overlength-strings.

That is totally different - that is an option specifically applying a
limit that is not required by any standard, but which can be helpful in
checking code for portability.

Even if the compiler were to have a "-Wblacklist-stdint" option, that
might help you detect it - but it would break C90 standards
compatibility, because C90 /allows/ you to have a <stdint.h>.

>>> Now, what actually mattered in my case was the use of (u)intmax_t.
>>> For instance, consider the following program:
>>> #include <stdio.h>
>>> #include <stdint.h>
>>> #include <limits.h>
>>> int main (void)
>>> {
>>>   uintmax_t i = -1;
>>>   printf ("%d\n", i > ULONG_MAX);
>>>   return 0;
>>> }
>>> In C90, "long" is the largest type, so that one should always expect
>>> the output 0. But:
>> "long" is the largest standards-mandated type in C90, but it is not
>> necessarily the largest type available.  An implementation is allowed to
>> provide additional types, even in "pedantic" C90 mode.
> I disagree.

The C90 standards document does not explicitly discuss extended integer
types (which are mentioned in C11, and I think C99 but I haven't
checked).  But there is nothing in the standard to stop an
implementation having them - it just has to use reserved identifiers for

>  Such types should yield a warning in "pedantic" C90 mode,
> just like other features that are not portable (see the above example
> with -Woverlength-strings, implied by -Wpedantic). IMHO, using
> intmax_t with an arbitrary C90 compiler is more problematic than
> using an overlength string (to some reasonable extent).

I still have trouble understanding why this is an issue.  If you are
writing code that needs to be C90 compatible, don't include <stdint.h>
and don't use intmax_t.  Problem solved.

To quote from the gcc reference for -Wpedantic:

> -Wpedantic does not cause warning messages for use of the alternate 
> keywords whose names begin and end with ‘__’. Pedantic warnings are
> also disabled in the expression that follows __extension__. However,
> only system header files should use these escape routes; application
> programs should avoid them. See Alternate Keywords. 
> Some users try to use -Wpedantic to check programs for strict ISO C
> conformance. They soon find that it does not do quite what they want:
> it finds some non-ISO practices, but not all—only those for which ISO
> C requires a diagnostic, and some others for which diagnostics have
> been added.
> A feature to report any failure to conform to ISO C might be useful
> in some instances, but would require considerable additional work and >
would be quite different from -Wpedantic. We donÂ’t have plans to
> support such a feature in the near future.

What you appear to be asking for is not supported by gcc, and not going
to be supported.

>> If you want to stick to C90, and you want to have a uintmax_t that
>> matches "long", then I suggest you don't include headers that are not
>                                  ^^^^^^^^^^^^^^^^^^^^^^^^^
>> relevant for C90, and define the types yourself.
> But that's the goal of -pedantic-errors!!! By using this option, I
> want to be able to detect the unconditional inclusion of <stdint.h>
> (actually I want it to be rejected by the autoconf test, which is
> the same thing in practice).

I thought autoconf tests were run using specific test code, not the
actual source code you are distributing.  Surely you can avoid
accidentally including <stdint.h> in the autoconf tests?  And surely a
quick "grep" will ensure that it is not used in the real source code?

>>  Perhaps start with:
>> #ifdef __STRICT_ANSI__
>> typedef long int intmax_t;
>> typedef unsigned long int uintmax_t;
>> #else
>> #include <stdint.h>
>> #endif
> The goal of -pedantic-errors is to *detect* that the developer writes
> something like the above instead of just:
> #include <stdint.h>

Since #include <stdint.h> does not break C90 conformity, then no.

You /could/ ask for a warning flag -Wno-oversized-integers that would
warn on the use of anything larger than "long" in C90 and anything
larger than "long long" in C99 - much the same as -Woverlength-strings.

More information about the Gcc-help mailing list