1

I have the code sample on a github repository and created a build on travis-ci for easy reproduction.

Minimal, Complete and Verifiable Example

probably not minimal, but I believe it's small enough

It creates a shared memory region using the boost.interprocess library (boost::interprocess::managed_shared_memory) and then creates a regular STL unordered_map using this regions' allocator from boost library.

The code is a stripped down version from my currently-closed-source library, inspired by the answer in the question std::unordered_map with boost::interprocess allocator in shared memory - drawbacks? by sehe

#include <sys/mman.h>
#include <sys/syscall.h>
#include <functional>
#include <memory>
#include <unordered_map>
#include <string>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/shared_memory_object.hpp>

class Thing {
 public:
  volatile Thing *_parent;
  explicit Thing(Thing *parent) : _parent(parent) {}
};

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, Thing> ThingMap;

int main() {
        boost::interprocess::shared_memory_object::remove("test");
        Segment my_segment{ipc::create_only, "test", 1ul<<40};
        Manager *my_manager = my_segment.get_segment_manager();
        ThingMap *my_map = my_segment.find_or_construct<ThingMap>("my_map")(my_manager);
        my_map->emplace(123, nullptr);
        printf("Hello world\n");
        return 0;
}

Questions

1. clang++ requires g++ installed?

Using Ubuntu 14.04, if I install clang++-6.0 or clang++-5.0 without updating g++ (default is version 4.9), I end up with compilation errors.

This is related to not having libc++ installed and clang not installing a c++ library by default and resorting to using what's in the system -- the one bundled with g++-4.9?

2. Does my code require GNU extensions?

Apparently if I specify -std=c++17, it will fail with g++-8. However, it will succeed with g++-7 and g++-6.

Since I was installing g++-8 in the clang builds, they also fail. My guess is that if I used g++-7, they would have succeeded. Build details with -std=c++17


Any best-practices advice is greatly appreciated. This is one of my few first attempts in using clang in travis-ci, or clang in general.

João Neto
  • 1,732
  • 17
  • 28

1 Answers1

3

1. clang++ requires g++ installed?

No -- but will use whatever standard library is available in the system.

In this case it's because it's an old library version. Installing libstdc++-8-dev solves the issue.

2. Does my code require GNU extensions?

Yes. As explained to me here by @jonathan-wakely

the allocator's value type is not the same as the container's value type (which is exactly what the error tells you!)

GCC will accept it as an extension in -std=gnu++17 mode, but you compiled with -std=c++17 which disables the non-standard extension.

Shouldn't it be also flagged as an error in gcc-6 and gcc-7 with -std=c++17?

No because the static assertion was only added in gcc 8.

The standard way is using HashMap = std::unordered_map<K, V, KH, KEq, Alloc<std::pair<const K, V>>>;

(Thanks to @jonathan-wakely for dealing with my noobish questions!)

Community
  • 1
  • 1
João Neto
  • 1,732
  • 17
  • 28