Boost logo

Boost Users :

Subject: Re: [Boost-users] libboost_date_time: undefined reference to __sync_fetch_and_add_4
From: Carsten Raas (carsten.raas_at_[hidden])
Date: 2009-04-06 14:33:47


Am 06.04.2009 14:24, Peter Dimov schrieb:
> Carsten Raas:
>
>> Finally, I tried to compile my demo program with the "-H" flag. Then I
>> grep'ed all included header files for "sync_fetch". The only file with
>> "sync_fetch" in it is atomicity.h and it appears three times, cf. the
>> dependency tree:
>> /opt/boost/1.38/intel/include/boost/date_time/date_generators.hpp
>> /usr/include/c++/4.2.1/stdexcept
>> /usr/include/c++/4.2.1/string
>> /usr/include/c++/4.2.1/bits/basic_string.h
>> /usr/include/c++/4.2.1/ext/atomicity.h
>> /usr/include/c++/4.2.1/sstream
>> /usr/include/c++/4.2.1/istream
>> /usr/include/c++/4.2.1/ios
>> /usr/include/c++/4.2.1/bits/ios_base.h
>> /usr/include/c++/4.2.1/ext/atomicity.h
>> /usr/include/c++/4.2.1/bits/locale_classes.h
>> /usr/include/c++/4.2.1/ext/atomicity.h
>
> So, it is what I thought; <string> and <istream> use
> __sync_fetch_and_add, not Boost.

Yes, these headers include atomicity.h.
But they don't trigger the problem directly:

#include <iostream>
#include <string>
#include <istream>
int main()
{ std::string s="test"; std::cout << s << std::endl; }

Works fine, if compiled with Intel icpc.
# icpc string_istream.cpp
------------------------------------------------------------------------
Linking with shared libboost_date_time fails:

# icpc -L /opt/boost/1.38/intel/lib string_istream.cpp \
        -lboost_date_time-il
/opt/boost/1.38/intel/lib/libboost_date_time-il.so:
undefined reference to `__sync_fetch_and_add_4'

So, using libstdc++ headers itself does not trigger the problem.
In some sense the boost library build manages to "break" it.
And only for the shared library. Very strange.
------------------------------------------------------------------------
The block

#ifdef _GLIBCXX_ATOMIC_BUILTINS
  static inline _Atomic_word
  __exchange_and_add(volatile _Atomic_word* __mem, int __val)
  { return __sync_fetch_and_add(__mem, __val); }

  static inline void
  __atomic_add(volatile _Atomic_word* __mem, int __val)
  { __sync_fetch_and_add(__mem, __val); }
#else

in atomicity.h might be the bad part. So I disabled this block and only
activate the #else part:

#else
  _Atomic_word
  __attribute__ ((__unused__))
  __exchange_and_add(volatile _Atomic_word*, int);

  void
  __attribute__ ((__unused__))
  __atomic_add(volatile _Atomic_word*, int);
#endif

NOW it works.
------------------------------------------------------------------------
I wanted to use the bjam flags
        <compileflags>-U _GLIBCXX_ATOMIC_BUILTINS
        <compileflags>-u _GLIBCXX_ATOMIC_BUILTINS
first, but this didnt' work out.

So I provide different bits/c++config.h (where _GLIBCXX_ATOMIC_BUILTINS
is defined) to build a clean (linkable) Boost library:

/* Predefined symbols and macros:
   wrapper for Intel compilers and Boost */

/* original c++config,
   i.e. /usr/include/c++/4.2.1/x86_64-suse-linux/bits/c++config.h */
#include <bits/c++config.gcc.h>

/* Define if builtin atomic operations are supported on this host. */
#if defined(__INTEL_COMPILER)
#undef _GLIBCXX_ATOMIC_BUILTINS
#endif
------------------------------------------------------------------------

I don't think this is a good solution.

But I cannot figure out where is the source of the problem:
libstdc++42 <-> boost <-> icpc

As the static libraries worked, one could guess it's a compiler bug. But
then nobody would have been able to build shared boost with the Intel
compiler suite (version 10 and 11)!?

-Carsten


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net