Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
Babysitter
210 / 127 / 50
Регистрация: 23.11.2015
Сообщений: 374
Завершенные тесты: 2
1

Std::atomic выбор конструктора

18.03.2016, 13:27. Просмотров 661. Ответов 10

недавно коллега вкомитил строчку вроде этой
C++
1
    std::atomic<int> at = 3;
вкоммитил с чистой душой, потому как его пятнадцатая студия скомпилила без проблем..
gcc и clang дружно начали орать, что налицо использование конструктора копирования, который не существует.
соответственно, такая формулировка, естественно, вызвала верный конструктор и сняла все вопросы.
C++
1
std::atomic<int> at(3);
C++
1
std::atomic<int> at{3};
ну вопрос понятен, в строчке типа
C++
1
std::string s = "hello";
ни о каком копировании речь не идет, как и в простейших сэмплах типа

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;
 
class A {
public:
    A(int foo) {
        cout << "int constructor" << endl;
    }
    A(const A& foo) {
        cout << "copy constructor" << endl;
    }
};
 
int main()
{
    A bar = 5;
    return 0;
}
что такого в том std::atomic, что заставляет его использовать несуществующий конструктор?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.03.2016, 13:27
Ответы с готовыми решениями:

Std::atomic vs std::mutex
class AtomicSome { private: std::atomic_bool _isReady;...

Стоит ли использовать std::atomic?
Доброго времени суток. Есть переменная в &quot;поток 2&quot; (назовем так) const...

Std::atomic и другие объекты
Добрый день! Подскажите пожалуйста можно ли создать ...

Пример о необходимости std::atomic
Изучаю std::atomic. Пытаюсь сделать пример, при котором приложение упадет, без...

Std::atomic. Реализация свободного от блокировок стека
Всем привет. Читаю книгу Параллельное программирование на с++ в действии Энтони...

10
ct0r
Игогошка!
1789 / 690 / 44
Регистрация: 19.08.2012
Сообщений: 1,342
Завершенные тесты: 1
18.03.2016, 16:15 2
Лучший ответ Сообщение было отмечено Babysitter как решение

Решение

Цитата Сообщение от Babysitter Посмотреть сообщение
что такого в том std::atomic, что заставляет его использовать несуществующий конструктор?
1) Ничего, это С++.
2) Использовать ничего не заставляет.
3) Замени
C++
1
2
3
A(const A& foo) {
        cout << "copy constructor" << endl;
    }
на
C++
1
A(const A& foo) = delete;
и удивись.

C++
1
std::atomic<int> at = 3;
По стандарту здесь создается временный объект std::atomic<int>(3), который затем используется для прямой инициализации - at(std::atomic<int>(3)). Чтобы эта семантика была верной, должен быть например конструктор копирования, очевидно же.
Да, реализациям в принципе позволено конструировать объект прямо на месте. Но это не значит, что при этом на правила языка забивается.
Синтаксис и семантика - первичны, оптимизации - вторичны.
5
Ilot
Эксперт С++
1832 / 1190 / 342
Регистрация: 16.05.2013
Сообщений: 3,139
Записей в блоге: 5
Завершенные тесты: 1
18.03.2016, 16:30 3
Цитата Сообщение от Babysitter Посмотреть сообщение
что такого в том std::atomic, что заставляет его использовать несуществующий конструктор?
Оператор копирования для atomic типов удален http://www.cplusplus.com/reference/atomic/atomic/atomic/
Связанно это с тем, что невозможно атомарно выполнить операцию над двумя объектами.
По определению атомарные операции не делимы. Однако если допустить существование конструктора копирования то теоретически возможно прерывание данной операции на стадии создания временного объекты, что не допустимо.
2
Babysitter
210 / 127 / 50
Регистрация: 23.11.2015
Сообщений: 374
Завершенные тесты: 2
08.11.2016, 22:39  [ТС] 4
в приведенном примере все оказалось проще, чем я думал.
ведь std::atomic не просто запрещено копирование, но еще и не описан move-конструктор
это означает, что неявно он тоже удален. нет копирования, нет перемещения, семантика языка первична.

сложнее с вот таким сэмплом.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;
 
class A {
public:
    A(int foo) {
        cout << "int constructor" << endl;
    }
    A(const A& foo) {
        cout << "copy constructor" << endl;
    }
    //A(A&& foo) = delete;
};
 
int main()
{
    A bar = 5;
    return 0;
}
компилиццо везде!
семантика языка говорит нам - сконструируй временный объект типа А,
сконструируй объект bar при помощи конструктора копирования.

стоит отметить, что раз конструктор копирования указан явно, то move-конструктор не был сгенерирован.
однако несмотря на то, что временный объект является правой ссылкой - происходит каст в левую и все работает.

но стоит нам запретить явно move-конструктор(которого и так не было!) и gcc с clang начинают плеваться,
vs2015 вроде компилит, но тут уже как повезет.

может кто-нибудь предпринять последнюю попытку разложить все по полочкам?
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4803 / 2454 / 687
Регистрация: 18.10.2014
Сообщений: 4,232
08.11.2016, 23:53 5
Цитата Сообщение от Babysitter Посмотреть сообщение
что такого в том std::atomic, что заставляет его использовать несуществующий конструктор?
В спецификации языка сказано, что даже если компилятор решил не использовать в таком контексте конструктор копирования (то есть выполнил оптимизацию "copy elision"), наличие такого конструктора все равно требуется, как будто никакой оптимизации не делалось.

Цитата Сообщение от Babysitter Посмотреть сообщение
но стоит нам запретить явно move-конструктор(которого и так не было!) и gcc с clang начинают плеваться,
Так и должно быть.

В первом случае move-конструктора совсем не было - он даже не был объявлен. Наличие явно объявленного copy-конструктора копирования подавляло неявное объявление move-конструктора.

Во втором случае move-конструктор объявлен, но как deleted - это уже совсем другое дело.

То есть "вообще не объявленная функция" и "функция, объявленная как deleted" - это совсем разные вещи. "Функции, объявленные как deleted" считаются объявленными, то есть они "существуют" и полноценно участвуют в overload resolution. Если deleted функция побеждает в overload resolution, то программа считается ошибочной. А "вообще не объявленные функции" нигде не участвуют - их просто нет.

Элементарный пример

C++
1
2
3
4
5
6
7
8
9
10
void foo(int);
 
void bar(int);
void bar(double) = delete;
 
int main()
{
  foo(1.0); // OK
  bar(1.0); // ERROR
}
Цитата Сообщение от Babysitter Посмотреть сообщение
vs2015 вроде компилит, но тут уже как повезет.
Баг в VS.
3
tapochka
40 / 40 / 17
Регистрация: 25.04.2014
Сообщений: 499
09.11.2016, 02:59 6
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
В спецификации языка сказано, что даже если компилятор решил не использовать в таком контексте конструктор копирования (то есть выполнил оптимизацию "copy elision"), наличие такого конструктора все равно требуется, как будто никакой оптимизации не делалось.
под дебагом запустил код babysittera про класс А - все равно нету конструктора копирования... почему copy-elision под дебагом сработала?
0
hoggy
Заблокирован
Эксперт С++
09.11.2016, 03:04 7
Цитата Сообщение от tapochka Посмотреть сообщение
почему copy-elision под дебагом сработала?
это - стандартная оптимизация.
стандарт определяет условия, когда она может сработать)
про дебаг там ничего не сказано))
1
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4803 / 2454 / 687
Регистрация: 18.10.2014
Сообщений: 4,232
09.11.2016, 03:37 8
Цитата Сообщение от tapochka Посмотреть сообщение
почему copy-elision под дебагом сработала?
А почему бы и нет? Отключения copy elision под дебагом никто не обещал. Более того, copy elision и NRVO - единственные разрешенные в С++ оптимизации, которые имеют право влиять на наблюдаемое поведение программы. Если бы они отключались под дебагом, то получалось бы, что дебажили мы одну программу, а релизим потом совсем другую. Зачем нам такой дебаг?
1
hoggy
Заблокирован
Эксперт С++
09.11.2016, 03:43 9
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
copy elision и NRVO - единственные разрешенные в С++ оптимизации, которые имеют право влиять на наблюдаемое поведение программы
RVO?
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4803 / 2454 / 687
Регистрация: 18.10.2014
Сообщений: 4,232
09.11.2016, 03:51 10
Цитата Сообщение от hoggy Посмотреть сообщение
RVO
Я имел в виду именно Named RVO.

"Классический" RVO был в С++ всегда, т.е. с С++98. Это лишь исключение безымянной промежуточной временной копии при возврате значения, т.е. самая что ни на есть традиционная форма copy elision образца 1998 года.

NRVO (Named RVO) появился только в С++03 и разрешил исключать даже именованный возвращаемый объект. Именно эту новую возможность я и имел в виду под NRVO.

Я навскидку считал NRVO чем-то отличным от copy elision, ибо привык называть copy elision только "классическое" исключение неименованных временных объектов. Однако я смотрю что в Инете термин copy elision смело применяют и к NRVO тоже (http://en.cppreference.com/w/cpp/language/copy_elision). Поэтому с этой точки зрения NRVO можно было бы даже и не упоминать, считая, что все виды RVO просто входят в copy elision.
4
hoggy
Заблокирован
Эксперт С++
09.11.2016, 04:16 11
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Поэтому с этой точки зрения NRVO можно было бы даже и не упоминать, считая, что все виды RVO просто входят в copy elision.
мерси
0
09.11.2016, 04:16
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.11.2016, 04:16

Шаблонные аргументы конструктора std::unique_ptr
Если я пишу код std::unique_ptr&lt;int, void(*)(int*)&gt; myPtr_5(new int,...

Std::vector добавить новый элемент собственного класса без использования конструктора копирования
Всем привет! Есть один класс, который я хочу хранить в std::vector. Создать...

Не воспринимает ни std::cout, ни std::cin. Вобщем ничего из std. Также не понимает iostream
Здравствуйте! Я хотел начать изучать язык C++. Набрал литературы. Установил...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru