Можно ли копировать std::atomic<bool> тривиально?

Следующий код выводит информацию о том, можно ли тривиально скопировать std::atomic<bool>:

#include <atomic>
#include <iostream>
#include <type_traits>

int main(){
    std::cout << std::is_trivially_copyable_v<std::atomic<bool>> << "\n";
}

Это дает следующий результат для gcc и clang:

1

демо (gcc+clang)

Но на MSVC результат:

0

Поведение всех трех компиляторов также демонстрируется здесь с помощью static_assert.

Я думал, что тривиальная возможность копирования в любом случае определяется стандартом.
Какой компилятор прав (или это зависит от реализации)?

en.cppreference.com/w/cpp/atomic/atomic гласит: «std::atomic нельзя ни копировать, ни перемещать». Теперь, возможно, для атомного bool gcc и clang реализовали способ его копирования, но я бы рекомендовал следующее стандарт
Nifil 25.04.2024 15:16
godbolt.org/z/oz5EK8b5q
Marek R 25.04.2024 15:18
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
13
2
1 559
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Проблема заключается в том, как работает trivyly_copyable. На самом деле вы не можете скопировать атомарный элемент в clang:

https://godbolt.org/z/dr3q3bns5

То же самое относится и к пользовательским некопируемым типам. Таким образом, единственный вопрос заключается в том, разрешено ли trivyly_copyable возвращать true для некопируемого типа. Можно было бы возразить, что, поскольку тип не может быть скопирован, у него нет нетривиальной операции копирования. Хотя мое собственное интуитивное ощущение подсказывает, что это должно давать «false» - в противном случае вам придется проверять is_copyable, а также trivally_copyable в некоторых случаях. Кто-то с большим знанием стандарта, возможно, сможет ответить на этот вопрос - я могу только сказать, что, основываясь на ссылке Cpp (https://en.cppreference.com/w/cpp/types/is_тривиально_copyable), я не знаю Не вижу никаких требований для этого случая.

Спасибо за ответ. Хотя я вижу причину в том, что вы написали, я не уверен в зависимости между копируемостью и тривиальной копируемостью. Смотрите комментарии под ответом Нифила.

wohlstad 25.04.2024 16:15
Ответ принят как подходящий

См. также: Можно ли тривиально скопировать класс с удаленным копирующим конструктором?

Удаленный конструктор не является нетривиальным.

До принятия резолюции CWG1734 для того, чтобы их можно было тривиально копировать, все конструкторы копирования/перемещения/операторы присваивания должны были быть тривиальными. Это касается std::atomic<bool> (они все удалены)

В новой формулировке его также нельзя было удалять (а в C++20 — «приемлемый», поскольку его ограничения удовлетворены).

GCC и Clang этого не реализуют. См.: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96288 https://github.com/llvm/llvm-project/issues/38398

Означает ли это, что MSVC здесь, а gcc/glang несовместимы?

wohlstad 25.04.2024 15:35

@wohlstad Да, MSVC в настоящее время верен, а GCC и clang соответствовали требованиям до февраля 2016 года.

Artyer 25.04.2024 15:39

Продолжение из комментариев:

en.cppreference.com/w/cpp/atomic/atomic гласит: «std::atomic нельзя ни копировать, ни перемещать». Я бы рекомендовал следовать стандарту.

Также, глядя на исходный код gcc, мы видим, что операторы копирования удалены.

Что касается возвращаемого значения std::is_тривиально_copyable_v, я думаю, что ответ @Juliean дает хорошее объяснение.

априори некопируемость (т. е. отсутствие жизнеспособного конструктора копирования) не означает, что std::trivially_copyable должно быть false. «Тривиально копируемый» - это копирование путем копирования байтов, то есть в обход конструкторов копирования.

463035818_is_not_an_ai 25.04.2024 15:54

Спасибо за ответ. Но я думаю, что, как упоминалось выше, тривиальная возможность копирования — это концепция, отдельная от «нормальной» возможности копирования/перемещения.

wohlstad 25.04.2024 16:03

@wohlstad Я взял определение отсюда en.cppreference.com/w/cpp/language/… Тривиально копируемый класс — это класс, который имеет хотя бы один подходящий конструктор копирования, конструктор перемещения, оператор присваивания копирования или присваивание перемещения. Каждый подходящий конструктор копирования тривиален. Каждый подходящий конструктор перемещения тривиален. Каждый подходящий оператор присваивания копирования тривиален. Каждый подходящий оператор присваивания перемещения тривиален и имеет неудаляемый тривиальный деструктор.

Nifil 25.04.2024 16:08

Я вижу сейчас. Поскольку я не языковой юрист, я не уверен, верна ли ваша интерпретация, но я вижу в этом причину.

wohlstad 25.04.2024 16:12

имхо, вам следует включить эту цитату в ответ. Заметьте, я не говорил, что вы не правы. Я просто говорю, что ваш ответ содержит молчаливое предположение, что если тип невозможно скопировать с помощью конструктора копирования, то его нельзя тривиально скопировать, я не думаю, что это очевидно и что это должно быть частью ответа.

463035818_is_not_an_ai 25.04.2024 16:51

Кстати, насколько я понимаю цитату, было бы достаточно, если бы класс имел один конструктор перемещения, но не имел другого перемещения или копирования, и если этот конструктор перемещения тривиален, охватываются и другие пункты. (все еще не говорю, что вы неправы, просто пытаюсь прояснить свое замешательство)

463035818_is_not_an_ai 25.04.2024 16:55

Другие вопросы по теме