2010-07-16 14 views
5

sé que por la palabra clave volatile,Pregunta sobre la palabra clave volátil

volatile int k=7; 

que hacen alusión al compilador que la variable se puede cambiar en cualquier momento, pero ¿qué pasa con un simple int k=7? ¿Podemos cambiarlo en cualquier momento porque no es constante? ¿Que es diferente?

Respuesta

4

Se utiliza en la programación de bajo nivel con las interrupciones y así sucesivamente mayoría

volatile int count; 

void test() 
{ 
    while(count< 100) 
    { 
     // do nothing 
    } 
} 

// 
// Interrupt function called by the hardware automatically at intervals 
// 
void interrupt() 
{ 
    count = count + 1; 
} 

si no declarar la variable como volátil, el compilador probablemente se dará cuenta de que la cuenta no se puede cambiar en el bucle while, etc. no se molestará en leer el valor cada vez desde la memoria para que nunca salga del ciclo.

Si se declara volátil entonces el compilador leerá el valor de la memoria cada vez que le has dicho a él que el valor podría cambiar sin previo aviso ...

Otro uso es para mapear puertos de hardware.

En un microcontrolador, es posible que tenga algunas entradas digitales que "aparecen" en una determinada dirección de memoria. Puede leerlos como si fueran una variable pero, por supuesto, el valor cambiará potencialmente todo el tiempo dependiendo de las señales de entrada. Declarar el valor como volátil indicará al compilador que sí, realmente necesita leer esta ubicación de memoria cada vez porque podría haber cambiado, y no puede suponer que no cambiará a menos que la cambie.

menos que esté utilizando interrupciones de nivel bajo o algunos usos de roscar, entonces no hay que usarla.

EDIT: Para ser claro, volátil no es para la sincronización entre theads en C++ estándar, sólo lo hace una parte de lo que es necesario. La última oración en mi publicación original podría ser engañosa. Los ejemplos y cosas sobre interrupciones de hardware, etc. en mi publicación son para lo que es volátil, NO ES para enhebrar y ni siquiera intenta usarlo para eso.

originalmente escribí "algunos usos de enhebrar" porque en algunas plataformas que podría ser suficiente para utilizar volátil. Esto es MAL AVISO en general, pero si tiene un solo núcleo y todas las escrituras son visibles para todos los "hilos", entonces podría funcionar para usted. Por ejemplo, en un microcontrolador con un simple sistema de conmutación de hilos basado en interrupciones, probablemente "funcionaría" aunque no esté garantizado por la norma. Pero no lo hagas En general, es un error, y C++ 11 tiene maneras que realmente funcionan (recuerda que esta respuesta fue escrito pre C++ 11)

+0

otra respuesta incorrecta. volátil no tiene nada que ver con el enhebrado e interrumpe –

+0

De hecho, una muy buena respuesta teniendo en cuenta la suya esencialmente dice lo mismo, además de mencionar cosas que el OP no solicita. –

+0

@AlexanderGessler "A menos que esté utilizando interrupciones de bajo nivel o algunos usos de subprocesamiento, entonces no necesita usarlo". –

18

volatile previene las optimizaciones del compilador y le dice al compilador que el contenido de la variable declarada volátil puede cambiar en cualquier momento (es decir, un dispositivo de hardware, interrupción u otro hilo inicia y escribe en la ubicación de la memoria de la variable). Esto significa que los valores de caché en los registros de la CPU no son posibles.

volatile int a = foo(); 
d=a+4; 
e=a+4; 
f=a+4; 

En este caso, el compilador se ve obligado a leer a de la memoria cada vez que se utiliza. Si no hubiera volatile, la precomputación a+4 sería una optimización válida (y efectiva).

volatile int a = 4; 
return a+5; 

Aquí, el compilador no está permitido para optimizar este a una simple return 9; porque los contenidos de a podrían cambiar entre inicialización (línea 1) y el primer uso (línea 2);

+0

su respuesta es incorrecta. volátil no tiene nada que ver con hilos e interrupciones. –

+0

No lo estoy diciendo tampoco; esos fueron solo ejemplos de casos en los que podría suceder que las variables cambien por razones externas al razonamiento del compilador. Su propia respuesta no es diferente a esta, excepto que conecta la información adicional de que 'volátil 'no se puede utilizar para la sincronización multiproceso, que no fue solicitada por el OP. –

+0

"interrupt, u ​​otro hilo entra y escribe en la ubicación de la memoria de la variable" + ejemplo = ciertamente sonó tan :) –

3

Cada vez que el compilador encuentra un acceso a k, volverá a extraerlo de la memoria en lugar de optimizar el código para colapsar múltiples usos de la misma.

int k = 7; 
int i = k; 
int j = k; 

se vuelve equivalente a:

int k = 7; 
int i; 
int j; 
i = j = k; 

pero

volatile int k = 7; 
int i = k; 
int j = k; 

no.

1

Volátil obliga a leer la variable de la memoria cada vez en lugar de almacenarla en caché.

0

podemos cambiar en cualquier momento, ya que no es constante?

Sí, puede cambiarlo, pero C++ no dice lo que debe suceder a continuación. Eso depende de la máquina abstracta (es decir, la plataforma en la que está trabajando).

Si la variable volátil no se asigna a un registro de un dispositivo de HW, a continuación, la variable volátil se comportará casi como una variable normal. He dicho casi, porque no va a ser capaz de pasar a métodos y funciones que esperan int no volátil, como éste:

void foo(int & p); 

Si los mapas de variables a un registro de un dispositivo de HW, a continuación, tratando de escribir a un registro de solo lectura depende del dispositivo. Simplemente puede ignorar las escrituras, pero también puede indicar un error, C++ no dice nada.


volatile es un cv-calificador, utilizado para acceder a los registros de hardware, o parte de la memoria que puede ser modificado externamente (por ejemplo, por un controlador).

El estándar de C++ en [dcl.type.cv]/7 dice:

[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 cambiado por medios indetectables por una implementación. Ver 1.9 para una semántica detallada. En general, la semántica de volátiles son pretenden ser el mismo en C++ como lo son en C. - nota final]

El artículo Stay away from Volatile in threaded code? dice lo que el volátil es bueno para:

La palabra clave volátil no es una primitiva de subprocesamiento o sincronización en C o C++ portátil. Se destina principalmente a

1) Permitir el acceso a dispositivos de red mapeadas de memoria (punteros es decir, a la estructura de datos en la memoria coherente que se pueden modificar por los dispositivos de E/S.)
2) Las variables en los manejadores de señales y entre setjmp y longjmp (ref: volátiles en Wikipedia)

otro artículo Volatile: Almost Useless for Multi-Threaded Programming dice:

Hans Boehm señala que sólo hay tres usos portátiles para volátil. Los resumiré aquí:
* marcando una variable local en el ámbito de un setjmp para que la variable no retroceda después de un longjmp.
* de memoria que es modificado por un agente externo o parece ser debido a una asignación de memoria chiflado
* manejador de señales mal

y

Si está multi-threading en aras de la velocidad, la ralentización del código definitivamente no es lo que quieres. Para la programación de subprocesos múltiples, existen dos problemas clave que a menudo se piensa que son volátiles:
* atomicity
* consistencia de la memoria, es decir, el orden de las operaciones de un subproceso visto por otro subproceso.

Lo que es importante es que volátil no deben utilizarse en el entorno multihilo como mecanismo de sincronización, o como para proporcionar acceso atómica, ya que puede funcionar en algunos compiladores, y no en otra. Para eso hay otras herramientas para sincronización (por ejemplo semáforos, o mutex con variable condicional) y acceso atómico (atomic library.

0

La palabra clave volátil se usa para informar al compilador de que no debe predecir/asumir/creer/suponer el valor del variable particular que ha sido declarado como volátil

Esta variable puede cambiar por fuentes internas y externas, por lo que definitivamente se puede cambiar

const volátil int k = 5;.. < ==== Esto podría no ser cambiar por su programa pero puede cambiar por fuentes externas, const solo lo hace de lectura, solo para compilador o programador

Fuente: - Volatile variable in C

Cuestiones relacionadas