La frase "sucede antes" se usa varias veces en el borrador del estándar C ++.
Por ejemplo: Terminación [basic.start.term] / 5
Si la finalización de la inicialización de un objeto con una duración de almacenamiento estático ocurre fuertemente antes de una llamada a std :: atexit (ver, [support.start.term]), la llamada a la función pasó a std :: atexit se secuencia antes de la llamada al destructor para el objeto. Si una llamada a std :: atexit ocurre fuertemente antes de la finalización de la inicialización de un objeto con duración de almacenamiento estático, la llamada al destructor para el objeto se secuencia antes de que la llamada a la función pase a std :: atexit . Si una llamada a std :: atexit ocurre fuertemente antes de otra llamada a std :: atexit, la llamada a la función pasada a la segunda llamada std :: atexit se secuencia antes de que la llamada a la función pase a primera llamada std :: atexit.
Y definido en Data racing [intro.races] / 12
Una evaluación A ocurre fuertemente antes de una evaluación D si, ya sea
(12.1) A se secuencia antes que D, o
(12.2) A se sincroniza con D, y tanto A como D son operaciones atómicas secuenciales consistentes ([atomics.order]), o
(12.3) hay evaluaciones B y C de manera que A se secuencia antes de B, B simplemente sucede antes de C y C se secuencia antes de D, o
(12.4) hay una evaluación B de manera que A ocurre fuertemente antes que B, y B sucede fuertemente antes de D.
[Nota: Informalmente, si A ocurre fuertemente antes que B, entonces A parece ser evaluado antes que B en todos los contextos. Sucede mucho antes de excluir las operaciones de consumo. - nota final]
¿Por qué se introdujo "fuertemente pasa antes"? Intuitivamente, ¿cuál es su diferencia y relación con "sucede antes"?
¿Qué significa "A parece ser evaluado antes que B en todos los contextos" en la nota?
(Nota: la motivación para esta pregunta son los comentarios de Peter Cordes bajo esta respuesta ).
Proyecto de presupuesto estándar adicional (gracias a Peter Cordes)
Orden y consistencia [atomics.order] / 4
Hay un único orden total S en todas las operaciones memory_order :: seq_cst, incluidas las cercas, que satisface las siguientes restricciones. Primero, si A y B son operaciones memory_order :: seq_cst y A sucede fuertemente antes que B, entonces A precede a B en S. Segundo, por cada par de operaciones atómicas A y B en un objeto M, donde A está ordenada por coherencia antes de B, S debe cumplir las siguientes cuatro condiciones:
(4.1) si A y B son ambas operaciones memory_order :: seq_cst, A precede a B en S; y
(4.2) si A es una operación memory_order :: seq_cst y B sucede antes de un memory_order :: seq_cst y Y, entonces A precede a Y en S; y
(4.3) si una cerca de memory_order :: seq_cst X ocurre antes de que A y B sea una operación memory_order :: seq_cst, X precede a B en S; y
(4.4) si una memoria_orden :: seq_cst cerca X ocurre antes de A y B sucede antes de una memoria_orden :: seq_cst cerca Y, entonces X precede a Y en S.
atexit()
en un subproceso y exit()
en otro, no es suficiente que los inicializadores lleven solo una dependencia basada en el consumo solo porque los resultados difieren de si exit()
fueron invocados por el mismo subproceso. Una respuesta anterior mía se refería a esta diferencia.
exit()
. Cualquier subproceso puede matar a todo el programa al salir, o el subproceso principal puede salir por return
-ing. Resulta en la llamada de los atexit()
controladores y la muerte de todos los hilos lo que sea que estuvieran haciendo.
seq_cst
, en Atomics 31.4 Orden y consistencia: 4 . Eso no está en el estándar C ++ 17 n4659 , donde 32.4 - 3 define la existencia de un único orden total de operaciones seq_cst consistentes con el orden "pasa antes" y los órdenes de modificación para todas las ubicaciones afectadas ; el "fuertemente" fue agregado en un borrador posterior.