¿El acceso a un objeto no volátil declarado a través de una referencia / puntero volátil confiere reglas volátiles a dichos accesos?

Esta será larga, para contextualizarla y proporcionar tanta información como pueda, debo deambular a través de varios enlaces y citas, ya que a menudo es la única forma una vez que ingresamos al Conejo estándar de C / C ++. Si tiene mejores citas o cualquier otra mejora en esta publicación, hágamelo saber. Pero para resumir por adelantado,puedes culpar a @zwol para mí publicar esto ;-) y el objetivo es encontrar la verdad entre dos proposiciones:

¿Los estándares C y (por importación; ver comentarios) C ++ requieren que los accesos a través devolatile * ovolatile & debe referirse a un objeto declarado originalmentevolatile para tenervolatile ¿semántica?Oestá accediendo a unvolatile-objeto calificado a través de unvolatile puntero / referencia suficiente / se supone que hace que dichos accesos se comporten como si el objeto fuera declaradovolatile?

Y de cualquier manera, si (como parece) la redacción es algo ambigua en comparación con la intención,podemos aclarar eso en los estándares mismos?

La primera de estas interpretaciones mutuamente excluyentes se lleva a cabo más comúnmente, y eso no está completamente sin fundamento. Sin embargo, espero mostrar que hay una cantidad significativa de "dudas razonables" a favor de la 2da, especialmente cuando volvemos a algunos pasajes anteriores en los Documentos de Fundamento y WG.


Sabiduría aceptada: el objeto referido en sí mismo debe haber sido declaradovolatile

Pregunta popular de ayer¿La definición de "volátil" es volátil, o GCC tiene algunos problemas de cumplimiento estándar? surgió asumiendo unvolatile referencia conferiríavolatile comportamiento en un novolatile referente, pero descubriendo que no lo hizo, o lo hizo en diversos grados y de manera impredecible.

La respuesta aceptada inicialmente concluyó que solo importaba el tipo declarado de referente. Esto y la mayoría de los comentarios parecían estar de acuerdo en que hay principios equivalentes en juego, como sabemos bien porconst: el comportamiento solo seríavolatile (o definido en absoluto) si la referencia tiene el mismoCV-calificación como el objeto referido:

La palabra clave en ese pasaje es objeto.volatile sig_atomic_t flag; Es un objeto volátil.*(volatile char *)foo es simplementeun acceso a través de un valor l volátil calificado y el estándar no requiere que tenga ningún efecto especial. -zwol

Esta interpretación parece ser bastante extendida, como se ve en las respuestas a esta pregunta similar, pero con suerte no duplicada:Requisitos para el comportamiento de puntero a volátil apuntando a objeto no volátil Pero hay incertidumbre incluso allí: ¡justo después de que la respuesta dice 'no', luego dice 'tal vez'! De todos modos ... revisemos el Estándar para ver en qué se basan los 'no'.


Lo que dice el estándar ... o no

C11N1548, §6.7.3: Considerando que está claro que es UB acceder a un objetodefinido con volatile oconst escriba a través de un puntero que no comparte dicho calificador ...

6 Si se intenta modificar un objeto definido con unconsttipo calificado mediante el uso de un valor l conconst-calificado tipo, el comportamiento es indefinido. Si se intenta hacer referencia aun objeto definido con unvolatiletipo calificado mediante el uso de un valor con novolatile-tipo calificado, el comportamiento es indefinido. (133)

... el Estándar no parece mencionar explícitamente el escenario opuesto, es decir, paravolatile. Además, al resumirvolatile y operaciones al respecto, ahora habla de un objeto quetiene volatile-tipo calificado:

7 Unobjeto que tienevolatiletipo calificado puede modificarse de formas desconocidas para la implementación o tener otros efectos secundarios desconocidos. Por lo tanto, cualquier expresión que se refiera a dicho objeto se evaluará estrictamente de acuerdo con las reglas de la máquina abstracta, como se describe en 5.1.2.3. Además, en cada punto de secuencia, el último valor almacenado en el objeto debe coincidir con el prescrito por la máquina abstracta, excepto por lo modificado por los factores desconocidos mencionados anteriormente. (134) Lo que constituye un acceso a un objeto que tienevolatileEl tipo calificado está definido por la implementación.

¿Debemos suponer que "tiene" es equivalente a "se definió con"? opuede "tiene" se refiere a una combinación de objeto y calificadores de referencia?

Un comentarista resumió bien el problema con este tipo de redacción:

Den1548 §6.7.3 ¶6 el estándar usa la frase "objeto definido con un tipo calificado volátil" para distinguirlo de "valor con tipo calificado volátil". Es desafortunado que este "objeto definido con la distinción" versus "lvalue" no se lleve adelante, y el estándar luego usa "objeto que tiene un tipo volátil calificado", y dice que "lo que constituye el acceso a un objeto que tiene un tipo volátil calificado" está definido por la implementación "(que podría haber dicho" lvalue "u" objeto definido con "para mayor claridad). Oh bien. -Dietrich Epp

El párrafo 4 de la misma sección parece ser citado con menos frecuencia, pero podría ser relevante, como veremos en la siguiente sección.


Dudas razonables: es / fue unvolatile puntero / referencia destinado a conferirvolatile semántica en su desreferencia?

La respuesta antes mencionada tiene un comentario en el que el autor cita una declaración anterior del Comité que arroja dudas sobre la idea de "la referencia debe coincidir con el referente":

Curiosamente, hay una oración allí [C99 Justificación devolatile] eso implica que el comitésignificaba para*(volatile T*)x para forzar ese acceso ax ser tratado como volátil; pero la redacción real de la norma no logra esto. - zwol

Podemos encontrar un poco más de información sobre esta parte de la justificación, del segundo hilo mencionado anteriormente:Requisitos para el comportamiento de puntero a volátil apuntando a objeto no volátil

Por otra parte,esta publicación citas del 6.7.3 de la Justificación de la Norma Internacional - Lenguajes de programación - C:

Un lanzamiento de un valor a un tipo calificado no tiene efecto; la calificación (por ejemplo, volátil) no puede tener efecto en el acceso, ya que se produjo antes del caso.Si es necesario acceder a un objeto no volátil utilizando una semántica volátil, la técnica consiste en convertir la dirección del objeto al tipo apropiado de puntero a calificado, luego desreferenciar ese puntero.

filipina

Y deese hilo Bytes, nos remiten a C99 s6.7.3 p3 - también conocido como p11 de C11 - y este análisis:

El párrafo en cuestión es justo antes de la sección 6.7.3.1 en el documento de justificación. Si también necesita citar el documento estándar en sí, cite6.7.3 p3:

Las propiedades asociadas con los tipos calificados son significativas solo para expresiones que son valores.

La expresion(volatile WHATEVER) non_volatile_object_identifier esno un lvalue, por lo tanto, el calificador 'volátil' no tiene sentido.

Por el contrario, la expresión* (volatile WHATEVER *) & non_volatile_object_identifier es un valor (puede colocarse en el lado izquierdo de una declaración de asignación), por lo que la propiedad del calificador 'volátil' tiene el significado deseado en este caso.

Tim Rentsch

Hay unmuy demostración específica que respalda esta idea, con respecto a la primera pregunta vinculada, enWG PaperN1381. Esto introdujo el anexomemset_s() hacer lo que ese OP quería: garantizar el llenado de memoria sin elidir. Al discutir posibles implementaciones, parece apoyar la idea, al omitir indicar cualquier requisito, que usar unvolatile puntero para alterar un novolatile objetodebería generar código basado en elcalificador del puntero, independientemente del objeto referido ...

Solución independiente de plataforma segura 'memset':
void *secure_memset(void *v, int c , size_t n) {
    volatile unsigned char *p = v;
    while (n--) *p++ = c;
    return v;
}

Este enfoque evitará que la limpieza de la memoria se optimice ydebería funcionar en cualquier plataforma que cumpla con los estándares.

... y que los compiladores que no hacen esto están en aviso ...

Ha habido un aviso reciente de quealgunos compiladores violan el estándar al no respetar siemprevolatile Calificatorio.


¿Quién tiene la razón?

Eso fue agotador. Ciertamente, hay mucho espacio para la interpretación aquí, dependiendo de qué documentos lees o no, y cómo elijas interpretar muchas palabras que no son lo suficientemente específicas. Parece claro que algo anda mal: o bien:

La justificación y el N1381 están redactados incorrectamente o al azar, ofueron invalidados específicamente retroactivamente ... ola Norma está redactada de manera incorrecta o al azar.

Espero que podamos hacerlo mejor que toda la ambigüedad y especulación que parece haber rodeado esto en el pasado, y obtener una declaración más concluyente registrada. Con ese fin, cualquier otra fuente y opinión de expertos sería muy bienvenida.

Respuestas a la pregunta(4)

Su respuesta a la pregunta