Bug 86977 - [g++ 8.1.0-5ubuntu1~14.04] error: static assertion failed: unordered container must have the same value_type as its allocator
Summary: [g++ 8.1.0-5ubuntu1~14.04] error: static assertion failed: unordered containe...
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 8.1.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-08-16 09:43 UTC by João Neto
Modified: 2018-08-16 10:29 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description João Neto 2018-08-16 09:43:59 UTC
**I'm not sure this is a bug; but I couldn't find alternate root cause. Sorry if it's not!**

The following code can be compiled successfully in `g++-6` and `g++-7`, but not in `g++-8`, which results in an error:

```
In file included from /usr/include/c++/8/unordered_map:46,
                 from /usr/include/c++/8/functional:61,
                 from test.cpp:3:
/usr/include/c++/8/bits/hashtable.h: In instantiation of ‘class std::_Hashtable<int, std::pair<const int, Thing>, boost::interprocess::allocator<void, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >’:
/usr/include/c++/8/bits/unordered_map.h:105:18:   required from ‘class std::unordered_map<int, Thing, std::hash<int>, std::equal_to<int>, boost::interprocess::allocator<void, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> > >’
test.cpp:30:15:   required from here
/usr/include/c++/8/bits/hashtable.h:192:21: error: static assertion failed: unordered container must have the same value_type as its allocator
       static_assert(is_same<typename _Alloc::value_type, _Value>{},
                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```

```
#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;
}

```

The code can be seen on GitHub, and there is a Travis build reproducing the issue. I've posted on StackOverflow but got no replies.

https://github.com/joaomlneto/clang-tidbit
https://travis-ci.com/joaomlneto/clang-tidbit/builds/81896897
https://stackoverflow.com/questions/51858747/compilation-tidbits-on-g-clang-using-libboost-g8-compilation-fails-wh

Using `libboost 1.54` (default for `apt-get install libboost-all-dev` in Ubuntu 14.04).
Compiled with `$(CXX) -std=c++17 $^ -o $@ -pthread -ldl -rdynamic -lrt`

If I change to `-std=gnu++17`, then it works.
https://travis-ci.com/joaomlneto/clang-tidbit/builds/81897835


Below is information on the system (although is a pretty standard Ubuntu 14.04):


```
# g++-8 -v
Using built-in specs.
COLLECT_GCC=g++-8
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/8/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 8.1.0-5ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-8 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=gcc4-compatible --disable-libstdcxx-dual-abi --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 8.1.0 (Ubuntu 8.1.0-5ubuntu1~14.04)
```

```
# uname -a
Linux d0710afa7fb5 4.15.0-30-generic #32-Ubuntu SMP Thu Jul 26 17:42:43 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
```

```
# lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 14.04.5 LTS
Release:	14.04
Codename:	trusty
```
Comment 1 Jonathan Wakely 2018-08-16 09:53:01 UTC
(In reply to João Neto from comment #0)
> using HashMap = std::unordered_map<K, V, KH, KEq, Alloc<void>>;

This is invalid, 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.
Comment 2 João Neto 2018-08-16 10:16:27 UTC
Hi Jonathan! Thanks for the quick reply!

Two follow-up questions:

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

(2) How can I reliably find the node-type allocated by the map if I'd want to use `-std=c++17`? Isn't it implementation-defined?

https://stackoverflow.com/questions/49736817/stdunordered-map-with-boostinterprocess-allocator-in-shared-memory-drawbac/49738871#49738871
Comment 3 João Neto 2018-08-16 10:19:45 UTC
> 
> (2) How can I reliably find the node-type allocated by the map if I'd want
> to use `-std=c++17`? Isn't it implementation-defined?
> 

Please ignore my stupidity. c++17 has a `node_type`

The other one I think is relevant though.

(Sorry for the spam!)
Comment 4 Jonathan Wakely 2018-08-16 10:29:11 UTC
(In reply to João Neto from comment #2)
> Hi Jonathan! Thanks for the quick reply!
> 
> Two follow-up questions:
> 
> (1) 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.

> (2) How can I reliably find the node-type allocated by the map if I'd want
> to use `-std=c++17`? Isn't it implementation-defined?

(In reply to João Neto from comment #3)
> Please ignore my stupidity. c++17 has a `node_type`

No, that's nothing to do with it.

Read the error message! Or read comment 1!

The allocator's value type must be the same as the container's VALUE TYPE. Not its node type. I really don't know how to make the static assertion any clearer.

The container's value_type is std::pair<const K, V>.