2010-06-05 16 views
8

En los talones de a specific problem, una auto-respuesta y comentarios, me gustaría entender si es una solución adecuada, solución/pirateo o simplemente incorrecta.Alias ​​de puntero estricto: ¿es el acceso a través de un puntero/referencia 'volátil' una solución?

Específicamente, Reescribí código:

T x = ...; 
if (*reinterpret_cast <int*> (&x) == 0) 
    ... 

Como:

T x = ...; 
if (*reinterpret_cast <volatile int*> (&x) == 0) 
    ... 

con un calificador volatile al puntero.

Supongamos que tratar T como en mi situación tiene sentido. ¿Este acceso a través de una referencia volatile soluciona el problema de alias del puntero?

Para una referencia, a partir de la especificación:

[Nota: volátil es un indicio a la aplicación para evitar agresiva optimización que implica el objeto debido a que el valor del objeto podría ser cambiada por medio indetectables por una implementación. Ver 1.9 para semántica detallada. En general, la semántica de volátil están destinados que ser el mismo en C++ como lo son en C. - nota final]

EDIT:

El código anterior se ha solucionado mi problema al menos en GCC 4.5 .

+0

Esta pregunta es ** no ** claramente específica de C++. Los moldes de estilo C++ se pueden reescribir trivialmente en C. – curiousguy

+0

@curiousguy C y C++ tienen reglas de lenguaje diferentes, sin embargo –

+0

@MattMcNabb ¿Cómo son los diferentes WRT 'volátiles'? – curiousguy

Respuesta

15

Volatile no puede evitar el comportamiento indefinido aquí. Entonces, si te funciona con GCC, es suerte.

Supongamos que T es un POD. Entonces, la forma correcta de hacerlo es

T x = …; 
int i; 
memcpy(&i,&x,sizeof i); 
if (i==0) 
    … 

¡Allí! Ningún problema estricto de aliasing y ningún problema de alineación de memoria. GCC incluso maneja memcpy como una función intrínseca (no se inserta una llamada de función en este caso).

+1

"Volátil no puede evitar el comportamiento indefinido aquí", ¿por qué? ¿Tienes alguna fuente para esta declaración? – doublep

+5

C++ estándar, sección 3.10 párrafo 15 es el lugar que debe consultar con respecto al alias estricto. No se menciona una excepción que implique volatilidad. – sellibitze

+0

Hay casos en que no es un comportamiento indefinido. Por ejemplo 'struct A {int a; }; int main() {X x; * reinterpret_cast (& x) = 10; } 'está bien y perfectamente definido de acuerdo con' 9.2/17'. El objeto es de tipo 'int', y lvalue también es de tipo' volatile int', por lo que el alias va bien. –

-3

Volatile no puede evitar el comportamiento indefinido aquí.

Bueno, cualquier cosa con respecto a volatile es poco clara en la norma. En general estoy de acuerdo con tu respuesta, pero ahora me gustaría discrepar un poco.

Para entender lo que significa volatile, el estándar no está claro para la mayoría de las personas, especialmente algunos escritores de compiladores. Es mejor pensar: cuando se usa volatile (y solo cuando), C/C++ es prácticamente el ensamblaje de alto nivel.

Al escribir en volatile lvalue, el compilador emitirá una TIENDA o varias TIENDAS si una no es suficiente (volatile no implica atómico).

Al escribir en volatile lvalue, el compilador emitirá una CARGA, o CARGA múltiple si no es suficiente.

Por supuesto, cuando no hay LOAD o STORE explícito, el compilador simplemente emitirá instrucciones que implican una CARGA o ALMACENAMIENTO.

sellibitze dio la mejor solución: use memcpy para reinterpretaciones de bits.

Pero si todos los accesos a una región de memoria se realizan con volatile lvalues, es perfectamente claro que las reglas de alias estricto no se aplican. Esta es la respuesta a tu pregunta.

+0

¿Por qué el voto a favor? – curiousguy

+6

-1: Primero, este no es un foro; no abordamos otras respuestas en las respuestas. Si cree que tiene una respuesta mejor, escriba una respuesta que aborde la pregunta. En segundo lugar y más importante, "cualquier cosa con respecto a la volatilidad es poco clara en el estándar". No, no lo es. El estándar es * muy * claro sobre qué tan volátil y no volátil funciona con respecto a la máquina abstracta. –

+1

@NicolBolas "_Segundo y más importante," todo lo relacionado con la volatilidad no está del todo claro en el estándar. "No, no lo es._" Mucha gente piensa que no está muy claro. Si crees que está claro, explica qué significa y mi interpretación es correcta. – curiousguy

Cuestiones relacionadas