0xbadf00d
class MyClass
{
int x, y;
void foo() volatile {
// do stuff with x
// do stuff with y
}
};
¿Necesito declarar? x
y y
como volatile
o serán todas las variables miembro tratadas como volatile
¿automáticamente?
Quiero asegurarme de que “cosas con x
” no se reordena con ” cosas con y
” por el compilador.
EDITAR: ¿Qué sucede si estoy lanzando un tipo normal a un volatile
¿tipo? ¿Esto indicaría al compilador que no reordene el acceso a esa ubicación? Quiero pasar una variable normal en una situación especial a una función cuyo parámetro es volátil. Debo asegurarme de que el compilador no reordene esa llamada con lecturas y escrituras anteriores o seguidas.
templatetypedef
Marcar una función miembro volatile
es como marcarlo const
; significa que el objeto receptor se trata como si fuera declarado como un volatile T*
. En consecuencia, cualquier referencia a x
o y
será tratado como un volatile
leer en la función miembro. Además, un volatile
el objeto solo puede llamar volatile
funciones de miembro.
Dicho esto, es posible que desee marcar x
y y
volatile
de todos modos, si realmente desea que todos los accesos a ellos sean tratados como volatile
.
Tú no tiene que declarar las variables miembro explícitamente ..
De documentos estándar 9.3.2.3,
Similarmente, semántica volátil (7.1.6.1) aplicar en funciones de miembros volátiles al acceder al objeto y sus miembros de datos no estáticos.
ereOn
El siguiente código:
#include <iostream>
class Bar
{
public:
void test();
};
class Foo
{
public:
void test() volatile { x.test(); }
private:
Bar x;
};
int main()
{
Foo foo;
foo.test();
return 0;
}
Genera un error al compilar con gcc:
main.cpp: In member function 'void Foo::test() volatile':
main.cpp:14:33: error: no matching function for call to 'Bar::test() volatile'
main.cpp:7:8: note: candidate is: void Bar::test() <near match>
Y desde un volatile
instancia no puede llamar a un non-volatile
método, podemos suponer que, sí, x
y y
será volatile
en el método, incluso si la instancia de MyClass
no se declara volatile
.
Nota: puede quitar el volatile
calificador usando un const_cast<>
si alguna vez lo necesita; Sin embargo, tenga cuidado porque al igual que const
hacerlo puede conducir a un comportamiento indefinido en algunos casos.
-
Corríjame si me equivoco en esto, pero ¿la semántica de las funciones volátiles no es como la de las funciones constantes en el sentido de que puede llamar a una función volátil en un objeto no volátil, pero no a una función no volátil de un objeto volátil?
– templatetypedef
28 de enero de 2011 a las 9:47
-
@ereOn- Una prueba rápida en
g++
sugiere que sí puedes llamarvolatile
funciones miembro de on-volatile
objetos. La razón quevolatile std::string
s son inútiles es porque si la cadena en sí esvolatile
solo puede llamarvolatile
funciones miembro, de las cuales no hay ninguna. $4.4.1 del estándar aclara que puede convertir un T* en un T* volátil implícitamente, y $9.3.1.3 dice que elvolatile
El calificador afecta althis
puntero, lo que sugiere que si tiene un objeto de tipoT
elthis
puntero de tipoT*
podría convertirse en unvolatile T*
para la llamada– templatetypedef
28 de enero de 2011 a las 9:56
-
@templatetypedef: Invertí la lógica (solo son las 7 am aquí; todavía necesito dormir un poco;)). Gracias, ya está arreglado. Puedes llamar a un
volatile
método de ambosvolatile
ynon-volatile
instancia. Pero si tu instancia esvolatile
no podrás llamarnon-volatile
métodos.– ereOn
28 de enero de 2011 a las 9:57
-
@ereOn: Entonces, es exactamente como para
const
, como dijo templatetypedef. La parte relevante, por supuesto, no es g ++, sino el estándar: la cláusula 4.4.1 parece indicarme que la necesaria conversión implícita dethis
deT*
avolatile T*
era completamente legal. También tenga en cuenta que 9.3.2.4 dice explícitamente que puede realizar una llamada a una función calificada cv si la expresión de objeto en la que la invoca es “tan calificada como cv o menos calificada como cv que la función miembro”. No se hace diferencia entreconst
yvolatile
en esta área.–Christopher Creutzig
28 de enero de 2011 a las 10:18
-
En cuanto a la conversión: si el objeto original en realidad se definió como volátil y accede a este objeto o a uno de sus miembros como un valor l (esencialmente, en el lado izquierdo de una asignación) como algo no volátil, cláusula 7.1.5.1.7 del estándar dice que el comportamiento del programa no está definido. No haga eso, incluso si funciona con la versión actual de su compilador actual en sus datos de prueba actuales. AFAICS, el elenco estaría bien para el acceso de solo lectura, al igual que para
const
.–Christopher Creutzig
28 de enero de 2011 a las 10:26
Así que usando el ejemplo original:
class MyClass
{
int x, y;
void foo() volatile {
// do stuff with x
// do stuff with y
// with no "non-volatile" optimization of the stuff done with x, y (or anything else)
}
void foo() {
// do stuff with x
// do stuff with y
// the stuff done with x, y (and anything else) may be optimized
}
};
relacionado stackoverflow.com/questions/2444734/…
– Peter Cordes
9 de septiembre de 2016 a las 0:09