bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

gnulib stdint.h substitution of int64_t results in a linking error in GC


From: Jarno Rajahalme
Subject: gnulib stdint.h substitution of int64_t results in a linking error in GCC 4.(3|2|0) on OSX, fix included
Date: Thu, 8 Apr 2010 20:24:02 -0700

I faced the following linking error trying to compile octave on OSX with GCC 
4.3 -m64:

dyld: Symbol not found: 
__ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE7seekoffElSt12_Ios_SeekdirSt13_Ios_Openmode
  Referenced from: 
/Users/rajahalm/testing/octave/src/.libs/liboctinterp-3.3.51+.dylib
  Expected in: flat namespace
 in /Users/rajahalm/testing/octave/src/.libs/liboctinterp-3.3.51+.dylib

unmangled:

std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> 
>::seekoff(long, std::_Ios_Seekdir, std::_Ios_Openmode)

/opt/local/lib/gcc43/libstdc++.6.dylib has an _almost_ matching entry:

__ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE7seekoffExSt12_Ios_SeekdirSt13_Ios_Openmode

unmangled:

std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> 
>::seekoff(long long, std::_Ios_Seekdir, std::_Ios_Openmode)

The difference is that the first parameter to seekoff() should be "long long", 
but it is "long", as it is of type std::streamoff, which is defined to be 
int64_t, if _GLIBCXX_HAVE_INT64_T is defined. This definition is handled 
differently in GCC 4.4, which does not exhibit this linking problem.

GCC 4.0 and 4.2 seem to have the same definition of std::streamoff as GCC 4.3, 
so this problem exists with those versions as well.

OSX /usr/include/stdint.h defines int64_t as "long long". As long as gnulib 
stdint.h redefines this as "long int" there is going to be this linking problem 
with GCC 4.3, even though both definitions result in the same size of the 
std::streamoff :-)

I tested this with the following change:

*** lib/stdint.in.h~    Fri Apr  2 17:38:10 2010
--- lib/stdint.in.h     Thu Apr  8 19:29:39 2010
***************
*** 135,141 ****
  
  /* Do not undefine int64_t if gnulib is not being used with 64-bit
     types, since otherwise it breaks platforms like Tandem/NSK.  */
! #if LONG_MAX >> 31 >> 31 == 1
  # undef int64_t
  typedef long int gl_int64_t;
  # define int64_t gl_int64_t
--- 135,141 ----
  
  /* Do not undefine int64_t if gnulib is not being used with 64-bit
     types, since otherwise it breaks platforms like Tandem/NSK.  */
! #if LONG_MAX >> 31 >> 31 == 1 && !(defined (__APPLE__) && defined (__MACH__))
  # undef int64_t
  typedef long int gl_int64_t;
  # define int64_t gl_int64_t
  # define GL_INT64_T
  #elif defined _MSC_VER
  # undef int64_t
  typedef __int64 gl_int64_t;
  # define int64_t gl_int64_t
  # define GL_INT64_T
  #elif @HAVE_LONG_LONG_INT@
  # undef int64_t
  typedef long long int gl_int64_t;
  # define int64_t gl_int64_t
  # define GL_INT64_T
  #endif

(added lines above for reference)

This change causes int64_t to be defined as "long long int", which seems to be 
equivalent to "long long" for name mangling pusposes.

With this change this linking error disappears. However, more fundamentally, it 
seems that definition of int64_t based on a matching LONG_MAX is not enough in 
any 64 bit C++ system, due to the name mangling difference between long and 
long long. The proper thing would be to not redefine int64_t at all if it is 
already defined as any type that is 64 bits long.

  Jarno







reply via email to

[Prev in Thread] Current Thread [Next in Thread]