Se puede copiar la elisión a través de las declaraciones sincronizar con?

En el ejemplo a continuación, si ignoramos el mutex por un segundo, la elisión de copia puede eliminar las dos llamadas al constructor de copia.

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

user_type result = foo();

Ahora las reglas para la elisión de copia no mencionan el enhebrado, pero me pregunto si realmente debería suceder a través de tales límites. En la situación anterior, la copia final, en la máquina abstracta lógica entre hilos, ocurre después de que se libera el mutex. Sin embargo, si se omiten las copias, la estructura de datos resultante se inicializa dentro del mutex, por lo tanto, el entrelazado ocurre antes de que se libere el mutex.

Todavía tengo que pensar en un ejemplo concreto de cómo la elisión de copia realmente podría dar lugar a una condición de carrera, pero la interferencia en la secuencia de memoria parece que podría ser un problema. ¿Alguien puede decir definitivamente que no puede causar un problema, o alguien puede producir un ejemplo que realmente pueda romperse?

Para garantizar que la respuesta no solo aborde un caso especial, tenga en cuenta que la elisión de copia (según mi lectura) todavía se permite si tengo una declaración comonew (&result)( foo() ). Es decir,result no necesita ser un objeto de pila. @user_type en sí también puede funcionar con datos compartidos entre subprocesos.

Responde: Elegí la primera respuesta como la discusión más relevante. Básicamente, dado que el estándar dice que puede ocurrir una elisión, el programador solo tiene que tener cuidado cuando ocurre a través de los límites de sincronización. No hay indicación de si esto es un requisito intencional o accidental. Todavía nos falta algún ejemplo que muestre qué podría salir mal, así que tal vez no sea un problema de ninguna manera.

Respuestas a la pregunta(4)

Su respuesta a la pregunta