Этот код компилируется чисто и работает со всеми компиляторами, которые я пробовал, кроме GCC 8 (и текущего ствола GCC):

std::make_shared<volatile int>(0)

Я хотел бы знать:

  1. Правильно ли GCC 8 отказаться от этого кода?
  2. Есть ли заменитель, который примет GCC 8 (с той же семантикой и производительностью)? Мне известно о std::atomic, но семантика не та, поэтому предложения использовать его вместо volatile - не то, что я ищу.

См. Здесь: https://godbolt.org/z/rKy3od.

3
John Zwinck 11 Сен 2018 в 07:53

1 ответ

Лучший ответ

Согласно стандартному языку это несоответствие libstdc ++.

Вероятно, это ошибка. make_shared вызывает allocate_shared со стандартным распределителем, std::allocator<remove_const_t<T>>, где T - это тип совместно используемого объекта. Этот распределитель будет использоваться только для получения перекомпонованного распределителя для базового общего объекта (структуры, содержащей volatile int и атомарные счетчики). Так что вполне нормально объявить этот базовый объект как non const non volatile.

Это определение для make_shared будет работать:

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)...);
}
5
Oliv 11 Сен 2018 в 07:27