Sources Bugzilla – Bug 10990
Inconsistent definition of int64_t in sys/types and stdint.h
Last modified: 2009-11-22 17:42:33 UTC
I found it odd and problematic that two glibc headers seem to compete with each other regarding definition of int64_t (and probably uint64_t as well). It looks like it's either incomplete, or some update never made it's way into the source tree, or, there is some rarer side issue which comes up and that they headers are this way on purpose. Here are details: 1) Header file /usr/include/sys/types.h defines int64_t as follows: /* These types are defined by the ISO C99 header <inttypes.h>. */ # ifndef __int8_t_defined # define __int8_t_defined typedef char int8_t; typedef short int int16_t; typedef int int32_t; # if __WORDSIZE == 64 typedef long int int64_t; # elif __GLIBC_HAVE_LONG_LONG __extension__ typedef long long int int64_t; # endif # endif 2) Header /usr/include/stdint.h also defines int64_t but slightly differently: /* There is some amount of overlap with <sys/types.h> as known by inet code */ #ifndef __int8_t_defined # define __int8_t_defined typedef signed char int8_t; typedef short int int16_t; typedef int int32_t; # if __WORDSIZE == 64 typedef long int int64_t; # else __extension__ typedef long long int int64_t; # endif #endi # endif As the comment states, this file does repeat some type definitions. However, definition of int64_t is different, it is not guarded with __GLIBC_HAVE_LONG_LONG preprocessor definition. This difference causes problems, for example, when using some of libraries from Boost C++ collection and compiling with Comeau C/C++ Compiler front-end. Here is original report I submitted to Boost (https://svn.boost.org/trac/boost/ticket/3548). Here are small tests that present how use of sys/types.h vs stdint.h influence compilation result if int64_t type is used: 1) Include sys/types.h and compilation fails: ////// $ cat bad.cpp /////////////////////////////// #include <sys/types.h> #include <boost/cstdint.hpp> int main() { boost::int64_t a(0); return 0; } $ como -I/home/mloskot/dev/boost/_svn/trunk bad.cpp Comeau C/C++ 4.3.10.1 (May 7 2008 12:23:21) for LINUX_INTEL_ELF_Beta Copyright 1988-2008 Comeau Computing. All rights reserved. MODE:non-strict warnings C++ noC++0x_extensions "/home/mloskot/dev/boost/_svn/trunk/boost/cstdint.hpp", line 111: error: the global scope has no "int64_t" using ::int64_t; ^ "bad.cpp", line 5: error: namespace "boost" has no member "int64_t" boost::int64_t a(0); ^ 2) 1) Include stdint.h and compilation fails: ////// $ cat good.cpp ////////////////////////////// #include <stdint.h> #include <boost/cstdint.hpp> int main() { boost::int64_t a(0); return 0; } $ como -I/home/mloskot/dev/boost/_svn/trunk good.cpp Comeau C/C++ 4.3.10.1 (May 7 2008 12:23:21) for LINUX_INTEL_ELF_Beta Copyright 1988-2008 Comeau Computing. All rights reserved. MODE:non-strict warnings C++ noC++0x_extensions "good.cpp", line 5: warning: variable "a" was declared but never referenced boost::int64_t a(0); ^ It is important to notice that int64_t is defined only if __GLIBC_HAVE_LONG_LONG. I checked the two headers in current glibc git repository and it still includes those definitions of int64_t, thus I decided to submit bug report directly to glibc instead of Ubuntu team (I use glibc from Ubuntu packages): (http://sourceware.org/git/?p=glibc.git;a=blob;f=posix/sys/types.h#l160) (http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/generic/stdint.h#l34) Environment: * OS: Linux / Ubuntu 9.10 * GCC: gcc(Ubuntu 4.4.1-4ubuntu8) 4.4.1 * glibc: 2.10.1-0ubuntu15 (http://packages.ubuntu.com/karmic/libc6-dev)
(In reply to comment #0) > Environment: > * OS: Linux / Ubuntu 9.10 > * GCC: gcc(Ubuntu 4.4.1-4ubuntu8) 4.4.1 > * glibc: 2.10.1-0ubuntu15 (http://packages.ubuntu.com/karmic/libc6-dev) *** CORRECTION TO ENVIRONMENT *** I'm terribly sorry for my mistake. I've given details of my other machine/system. Here are correct details of system on which the problem leaks and on which I prepared the two test programs: * Linux Ubuntu 9.04 32-bit * GCC 4.3.3 * glibc 2.9-4ubuntu (http://packages.ubuntu.com/jaunty/libc6-dev) * Comeau C/C++ Compiler front-end 4.3.10.1 I've also changed the glibc version to which this report applies from 2.10 to 2.9. I'm sorry for confusion.
stdint.h is a C99 header and C99 demands the implementation of long long. The headers are correct.
The point here is that stdint.h behaves differently depending upon what has been #included previously, for example: #include <sys/types.h> // possibly included from some deep dependency #include <stdint.h> May *NOT* result in int64_t being defined if __GLIBC_HAVE_LONG_LONG is not set, where as had stdint.h been the first include then it *would* have been defined. In other words stdint.h may not follow the C99 std depending upon what has happened to be included previously. Still think it's not a bug? IMO stdint.h should always define int64_t no matter what other headers may have been included first. John Maddock.
You cannot have __GLIBC_HAVE_LONG_LONG *not* be defined if you include stdint.h.