On 2017-06-01 13:14 +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! > > > > > 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. For example we have __int128 and some targets has __int20. > In this particular case, uintmax_t is defined using the "__extension__" > keyword inside the <stdint.h> file. (At least, that is the case in my > sample <stdint.h> here.) The implementation is allowed to do that - the > identifier "__extension__" is reserved for the implementation, and the > compiler can use it however it wants. > > So in C90 mode, <stdint.h> is not standardised and can contain whatever > the implementation (or user) wants. The same applies to the type > "uintmax_t" - C90 says nothing about it. You have no guarantees, and > the working of the code depends entirely on the contents of <stdint.h>. > > 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. Perhaps start with: > > #ifdef __STRICT_ANSI__ > typedef long int intmax_t; > typedef unsigned long int uintmax_t; > #else > #include <stdint.h> > #endif It's wrong. __STRICT_ANSI__ is also defined in "-std=c99". We need #if defined(__STRICT_ANSI__) && __STDC_VERSION__ < 199901L #include <our/customized/stdint.h> #else #include <stdint.h> #endif > > > > cventin:~> gcc -std=c90 -pedantic-errors -o tst tst.c -m32 > > cventin:~> ./tst > > 1 > > > > under GNU/Linux. > > > > IMHO, at least some features of <stdint.h> should yield a warning > > with -pedantic (an error with -pedantic-errors). > > I'll send a RFC patch to gcc-patch, after finishing my baechlor thesis... But it's nearly impossible the patch would be approved by GCC developers. -- Xi Ruoyao <ryxi@xxxxxxxxxxxxxxxxx> School of Aerospace Science and Technology, Xidian University