Search code examples
c++compiler-errorsclang++llvm-clangboost-interprocess

Compilation successful with clang 5.0.1/6.0.0, fails with 5.0.2/6.0.1


TL;DR: Clang 6.0.0 compiles my program; 6.0.1 doesn't. Regression? Or due to incomplete testing? Bad code?

I have recently integrated Boost Interprocess in a library I am building. Works fine with GCC, but I get mixed results with Clang.

+---------------------------+-----------+-------------------+-------------------+
|          System           | GCC 6/7/8 | Clang 6.0.0/5.0.1 | Clang 6.0.1/5.0.2 |
+---------------------------+-----------+-------------------+-------------------+
| Ubuntu 14.04 (Travis)     | Succeeds  | Not available     | Fails (see below) |
| Linux Mint 19 (my laptop) | Succeeds  | Succeeds          | (?)               |
+---------------------------+-----------+-------------------+-------------------+

Prior to including Boost Interprocess, compiling with clang resulted in a few warnings related to GNU extensions...

warning: token pasting of ',' and __VA_ARGS__ is a GNU extension
      [-Wgnu-zero-variadic-macro-arguments]
  L->debug(LFMT fmt, __FILENAME__, __LINE__, __FUNCTION__, ##__VA_ARGS__);

...and macro expansions:

warning: extension used [-Wlanguage-extension-token]
  SET_WRAPPED(pthread_rwlock_init, pthread_handle);
  ^
/home/joaomlneto/Documents/GitHub/fpthreads/fpthreads/src/fpthread/util/wrap.cpp:14:16: note: expanded from macro 'SET_WRAPPED'
    WRAP(x) = (typeof(WRAP(x))) dlsym(handle, #x);\

But otherwise compiled successfully.

After I started using Boost Interprocess, instantiating an unordered_map in a shared_memory_segment results in a fatal error on clang 5.0.2/6.0.1 (versions on travis-ci), but succeeds on versions 5.0.1/6.0.0 (available in linux mint 19, which is the default for ubuntu 18.04). The code excerpt in question (inspired by https://stackoverflow.com/a/49738871/4288486) is the following:

namespace ipc = boost::interprocess;
using Segment = ipc::managed_shared_memory;
using Manager = Segment::segment_manager;
template <typename T> using Alloc = ipc::allocator<T, Manager>;
template <typename K, typename V, typename KH = std::hash<K>,
          typename KEq = std::equal_to<K>>
using HashMap = std::unordered_map<K, V, KH, KEq, Alloc<void>>;
typedef HashMap<pid_t, Thread> ThreadMap;
Manager *thread_mgr = _segment.get_segment_manager();
_threads = _segment.find_or_construct<ThreadMap>("threads")(thread_mgr);

Full output from Travis


Solution

  • clang was using the c++ library bundled in the system (my understanding is that it does not ship with one bundled, as g++ does?). By default, Ubuntu 14.04 includes g++-4.9's libstdc++, which was outdated (I guess).

    Installing e.g. libstdc++-8-dev solved my problem.