Может ли произойти копирование через операторы синхронизации с?

В приведенном ниже примере, если мы игнорируем мьютекс на секунду, копия elision может исключить два вызова конструктора копирования.

user_type foo()
{
  unique_lock lock( global_mutex );
  return user_type(...);
}

user_type result = foo();

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

Мне еще предстоит подумать о конкретном примере того, как исключение копирования может действительно привести к состоянию гонки, но вмешательство в последовательность памяти может показаться проблемой. Кто-нибудь может окончательно сказать, что это не может вызвать проблемы, или кто-то может привести пример, который действительно может сломаться?

Чтобы убедиться, что ответ не относится только к особому случаю, обратите внимание, что разрешение на копирование (согласно моим прочтениям) все еще разрешено, если у меня есть такое утверждениеnew (&result)( foo() ), Это,result не должен быть стековым объектом.user_type Сам по себе может также работать с данными, разделяемыми между потоками.

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

Ответы на вопрос(2)

Ваш ответ на вопрос