Eric Blake wrote: > And does it make a difference which of these four possibilities you use? > > 1. #include <stdint.h> > 2. #include <inttypes.h> > 3. #include <stdint.h> > #include <inttypes.h> > 4. #include <inttypes.h> > #include <stdint.h>
I reproduce the same error as Gary, on ia64-hp-hpux11.23 with aCC 6.17. i.c preprocessed with the gnulib headers (i.e. -I options): Regardless whether it starts with #include <stdint.h> or <inttypes.h>, the output is l1 (-((signed char)(127)) - 1) l2 ((signed char)(127)) l3 (-((short)(32767)) - 1) l4 ((short)(32767)) l5 (-2147483647l - 1) l6 2147483647l l7 ((unsigned char)(255)) l8 ((unsigned short)(65535)) l9 4294967295ul i.c preprocessed with the system headers (i.e. no -I options): Regardless whether it starts with #include <stdint.h> or #include <stdint.h> #include <inttypes.h> or #include <inttypes.h> #include <stdint.h> the output is l1 (-((signed char)(127)) - 1) l2 ((signed char)(127)) l3 (-((short)(32767)) - 1) l4 ((short)(32767)) l5 (-2147483647l - 1) l6 2147483647l l7 ((unsigned char)(255)) l8 ((unsigned short)(65535)) l9 4294967295ul But when it starts with #include <inttypes.h> the output is: l1 (-(127) - 1) l2 (127) l3 (-(32767) - 1) l4 (32767) l5 (-2147483647l - 1) l6 2147483647l l7 255u l8 65535u l9 4294967295ul This is explained by looking at /usr/include/stdint.h. It contains this code: #include <inttypes.h> ... #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) # undef INT8_C # define INT8_C(__c) ((signed char)(__c)) # undef UINT8_C # define UINT8_C(__c) ((unsigned char)(__c)) # undef INT16_C # define INT16_C(__c) ((short)(__c)) # undef UINT16_C # define UINT16_C(__c) ((unsigned short)(__c)) #endif /* !__cplusplus || __STDC_CONSTANT_MACROS */ So it is replacing an implementation of the INT8_C macro that works with the preprocessor but yields a wrong type, with an implementation that has the expression types right but fails in the preprocessor. The fix for gnulib is to recognize this case in stdint.m4, and arrange to override <stdint.h>. This implements it. 2009-02-25 Bruno Haible <[email protected]> Work around broken INT8_MAX, UINT8_MAX etc. values on HP-UX 11.23. * m4/stdint.m4 (gl_STDINT_H): Also check whether the expansions of INT8_MAX, UINT8_MAX etc. contain casts to elementary types. * doc/posix-headers/stdint.texi: Mention the HP-UX bug. Reported by Gary V. Vaughan <[email protected]>. --- doc/posix-headers/stdint.texi.orig 2009-02-26 01:16:25.000000000 +0100 +++ doc/posix-headers/stdint.texi 2009-02-26 01:15:21.000000000 +0100 @@ -19,6 +19,10 @@ @item The value of @code{WINT_MAX} is incorrect on some platforms: mingw. +...@item +The values of @code{INT8_MAX}, @code{UINT8_MAX} etc. are not usable in +preprocessor expressions on some platforms: +HP-UX 11.23. @end itemize Portability problems not fixed by Gnulib: --- m4/stdint.m4.orig 2009-02-26 01:16:25.000000000 +0100 +++ m4/stdint.m4 2009-02-26 01:11:15.000000000 +0100 @@ -1,4 +1,4 @@ -# stdint.m4 serial 33 +# stdint.m4 serial 34 dnl Copyright (C) 2001-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -201,7 +201,75 @@ int check_size: (size_t) -1 == SIZE_MAX ? 1 : -1; }; ]])], - [gl_cv_header_working_stdint_h=yes])]) + [dnl Determine whether the various *_MIN, *_MAX macros are usable + dnl in preprocessor expression. We could do it by compiling a test + dnl program for each of these macros. It is faster to run a program + dnl that inspects the macro expansion. + dnl This detects a bug on HP-UX 11.23/ia64. + AC_RUN_IFELSE([ + AC_LANG_PROGRAM([[ +#define __STDC_LIMIT_MACROS 1 /* to make it work also in C++ mode */ +#define __STDC_CONSTANT_MACROS 1 /* to make it work also in C++ mode */ +#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */ +#include <stdint.h> +] +gl_STDINT_INCLUDES +[ +#include <stdio.h> +#include <string.h> +#define MVAL(macro) MVAL1(macro) +#define MVAL1(expression) #expression +static const char *macro_values[] = + { +#ifdef INT8_MAX + MVAL (INT8_MAX), +#endif +#ifdef INT16_MAX + MVAL (INT16_MAX), +#endif +#ifdef INT32_MAX + MVAL (INT32_MAX), +#endif +#ifdef INT64_MAX + MVAL (INT64_MAX), +#endif +#ifdef UINT8_MAX + MVAL (UINT8_MAX), +#endif +#ifdef UINT16_MAX + MVAL (UINT16_MAX), +#endif +#ifdef UINT32_MAX + MVAL (UINT32_MAX), +#endif +#ifdef UINT64_MAX + MVAL (UINT64_MAX), +#endif + NULL + }; +]], [[ + const char **mv; + for (mv = macro_values; *mv != NULL; mv++) + { + const char *value = *mv; + /* Test whether it looks like a cast expression. */ + if (strncmp (value, "((unsigned int)"/*)*/, 15) == 0 + || strncmp (value, "((unsigned short)"/*)*/, 17) == 0 + || strncmp (value, "((unsigned char)"/*)*/, 16) == 0 + || strncmp (value, "((int)"/*)*/, 6) == 0 + || strncmp (value, "((signed short)"/*)*/, 15) == 0 + || strncmp (value, "((signed char)"/*)*/, 14) == 0) + return 1; + } + return 0; +]])], + [gl_cv_header_working_stdint_h=yes], + [], + [dnl When cross-compiling, assume it works. + gl_cv_header_working_stdint_h=yes + ]) + ]) + ]) fi if test "$gl_cv_header_working_stdint_h" = yes; then STDINT_H=
