Search code examples
c++c++11gccvolatilemake-shared

GCC 8 fails to compile make_shared<volatile int>()


This code compiles cleanly and works with all compilers I've tried except for GCC 8 (and current GCC trunk):

std::make_shared<volatile int>(0)

I'd like to know:

  1. Is GCC 8 correct to refuse this code?
  2. Is there a substitute that GCC 8 will accept (with the same semantics and performance)? I am aware of std::atomic, but the semantics are not the same so suggestions to use it instead of volatile are not what I'm looking for.

See it here: https://godbolt.org/z/rKy3od


Solution

  • According to the standard language this is a libstdc++ non conformance.

    This is probably a mistake. make_shared calls allocate_shared with a standard allocator, std::allocator<remove_const_t<T>> where T is the type of the shared object. This allocator will only be used to get a rebinded allocator for the underlying shared object (a struct which contains the volatile int and atomic counters). So it is perfectly fine to declare this underlying object as non const non volatile.

    This definition for make_shared will work:

    template<class T,class...Args>
    auto make_shared(Args&&...args){
        using ncvT= std::remove_cv_t<T>;
        return std::allocate_shared<T>(std::allocator<ncvT>(),std::forward<Args>(args)...);
    }