On GNU/kFreeBSD 7 (32-bit), which uses gcc 4.7.2, a current coreutils snapshot fails to build, with this error:
CC lib/libcoreutils_a-xmalloc.o In file included from /usr/include/sys/kern/types.h:71:0, from /usr/include/sys/kern/param.h:67, from /usr/include/osreldate.h:1, from /usr/include/i386-kfreebsd-gnu/sys/param.h:39, from ../lib/minmax.h:39, from ../lib/xmalloc.c:25: /usr/include/sys/_stdint.h:74:21: error: conflicting types for 'gl_intptr_t' In file included from ../lib/idx.h:26:0, from ../lib/xalloc.h:32, from ../lib/xmalloc.c:22: ./lib/stdint.h:317:18: note: previous declaration of 'gl_intptr_t' was here In file included from /usr/include/sys/kern/types.h:71:0, from /usr/include/sys/kern/param.h:67, from /usr/include/osreldate.h:1, from /usr/include/i386-kfreebsd-gnu/sys/param.h:39, from ../lib/minmax.h:39, from ../lib/xmalloc.c:25: /usr/include/sys/_stdint.h:78:22: error: conflicting types for 'gl_uintptr_t' In file included from ../lib/idx.h:26:0, from ../lib/xalloc.h:32, from ../lib/xmalloc.c:22: ./lib/stdint.h:318:27: note: previous declaration of 'gl_uintptr_t' was here make[2]: *** [lib/libcoreutils_a-xmalloc.o] Error 1 and similar errors in a couple of other .o files. What happens, is that - AC_PROG_CC enables the option '-std=gnu11', - The configure test from stdint.m4, which attempts to see whether SIZE_MAX is correctly defined, does this: #if 201112 <= __STDC_VERSION__ int k = _Generic (SIZE_MAX, size_t: 0); and this fails: configure:24271: checking whether stdint.h conforms to C99 configure:24448: gcc -std=gnu11 -c -g -O2 -I/home/bruno/include -Wall conftest.c >&5 conftest.c:332:1: warning: implicit declaration of function '_Generic' [-Wimplicit-function-declaration] conftest.c:332:29: error: expected expression before 'size_t' configure:24448: $? = 1 - As a result, the generated stdint.h replacement overrides the intptr_t and uintptr_t types via macros. - These macros cause syntax errors with the system include file: /usr/include/sys/_stdint.h This depends on the GCC version. See: ============================ foo.c ========================= #define __STDC_CONSTANT_MACROS 1 #define __STDC_LIMIT_MACROS 1 #include <stdint.h> #include <stddef.h> #if 201112 <= __STDC_VERSION__ int k = _Generic (SIZE_MAX, size_t: 0); #endif ============================================================ With gcc 4.6.4: $ gcc -std=gnu11 -S foo.c cc1: error: unrecognized command line option ‘-std=gnu11’ With gcc 4.7.3: $ gcc -std=gnu11 -S foo.c foo.c:6:1: warning: implicit declaration of function ‘_Generic’ [-Wimplicit-function-declaration] foo.c:6:29: error: expected expression before ‘size_t’ With gcc 4.8.5: $ gcc -std=gnu11 -S foo.c foo.c:6:1: warning: implicit declaration of function ‘_Generic’ [-Wimplicit-function-declaration] int k = _Generic (SIZE_MAX, size_t: 0); ^ foo.c:6:29: error: expected expression before ‘size_t’ int k = _Generic (SIZE_MAX, size_t: 0); ^ With gcc 4.9.4: $ gcc -std=gnu11 -S foo.c (success) Thus, the summary is: Don't believe __STDC_VERSION__ in this case. The following patch fixes it, by changing the configure test result from checking whether stdint.h conforms to C99... no to checking whether stdint.h conforms to C99... yes 2023-08-13 Bruno Haible <br...@clisp.org> stdint: Fix configure test result with gcc 4.7 or 4.8. * m4/stdint.m4 (gl_STDINT_H): Don't assume that _Generic works with GCC versions < 4.9 with -std=gnu11. diff --git a/m4/stdint.m4 b/m4/stdint.m4 index d6961b0993..b9f764d4c1 100644 --- a/m4/stdint.m4 +++ b/m4/stdint.m4 @@ -1,4 +1,4 @@ -# stdint.m4 serial 61 +# stdint.m4 serial 62 dnl Copyright (C) 2001-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -150,7 +150,10 @@ AC_DEFUN_ONCE([gl_STDINT_H] uintmax_t j = UINTMAX_MAX; /* Check that SIZE_MAX has the correct type, if possible. */ -#if 201112 <= __STDC_VERSION__ +/* ISO C 11 mandates _Generic, but GCC versions < 4.9 lack it. */ +#if 201112 <= __STDC_VERSION__ \ + && (!defined __GNUC__ || 4 < __GNUC__ + (9 <= __GNUC_MINOR__) \ + || defined __clang__) int k = _Generic (SIZE_MAX, size_t: 0); #elif (2 <= __GNUC__ || 4 <= __clang_major__ || defined __IBM__TYPEOF__ \ || (0x5110 <= __SUNPRO_C && !__STDC__))