2012-02-07 27 views
5

Hace pocos días tuve una entrevista, pero todavía estoy buscando la respuesta. Me gustaría entender la importancia de usar palabras clave volátiles.¿Cuál es la diferencia entre volátil y externo?

Encuentra el código a continuación: Dos escenarios diferentes.

//project1 
//File1.c 

int abc;//Global variable 
/*And this variable is getting used in some other files too.*/ 
if(abc == 3) //Say 
{ 
    printf("abc == 3"); 
} 
else 
{ 
    printf("abc != 3"); 
} 
/*So if or else part will not be optimized 
because "abc" can not be predicted, 
the value can chage at any point of time */ 




//Project2 
//file1.c 

volatile int abc;//Global variable with volatile keyword 

/*And this variable is getting used in some other files too.*/ 

if(abc == 3) //Say 
{ 
    printf("abc == 3"); 
} 
else 
{ 
    printf("abc != 3"); 
} 
/*So if or else part will not be optimized 
because "abc" can not be predicted as it is declared as volatile, 
the value can chage at any point of time */ 

¿Por qué deberíamos usar la palabra clave volátil en su lugar?

+0

posible duplicado de [¿Cuál es la diferencia entre una variable estática global estática y estática?] (Http: // stackoverflow.com/questions/346306/what-is-the-difference-between-a-static-global-and-static-volatile-variable) – NPE

+5

volátil y extern no tienen ninguna relación. –

+0

@MarkByers: Tiene razón, pero de acuerdo con la pregunta del entrevistador, ambos elementos sirven lo mismo. Entonces, ¿por qué volátil? –

Respuesta

5

Como Tony Delroy explicó en su comentario, extern y volatile son bastante diferentes.


volátil palabra clave protege la variable de ser optimizado de manera agresiva. Una variable optimizada puede ser invisible para otros hilos y nunca llegar a la memoria principal. A veces, el compilador puede even squeeze entirely una variable si no es necesario. El compilador basa su suposición con su código fuente como su única entrada. A veces, hay algunos eventos externos que pueden cambiar su valor de variable. Podría ser un dispositivo de hardware u otro proceso, por ejemplo.

=> En concreto, el compilador deshabilita algunas optimizaciones para esta variable, por lo que puede comportarse como usted lo desee.


Externo no se trata de caché vs memoria. Extern se trata de acceder a una variable que vive en otros archivos objeto. Consulte this short example de qué clase de código de ensamblado se genera para un extern acceso. Esas extern variables están optimizadas en su propio archivo de objeto en la medida de lo posible. No hay dudas sobre cómo protegerlo o no.

=> Concretamente, compilador indica una referencia externa que necesita ser resuelto en tiempo de enlace

+0

Punteros de marco y extern no están relacionados. Los punteros de marco se utilizan para variables de pila (clase de almacenamiento automático), extern son globales (clase de almacenamiento estático) y no necesitan ningún puntero de marco. – Suma

+0

Maldita sea, he vuelto a marcar y tienes razón. Eliminaré esta parte de mi respuesta – Coren

+1

La explicación de extern es confusa. –

4

volátil en la declaración o prototipo siempre digo cargar almacenar valor/de/a la memoria independientemente locales, estática o extern este vlaue (pero en el caso de lo local no siempre es significativo).

También usando palabra clave volátil en fuente normal son atípicamente. Solo es útil para hardware que asigna registros de hardware a la memoria (como en la arquitectura ARM), en casos especiales de desarrollo kernel/driver.

Si usa volátil en GUI o código de comercio electrónico, probablemente esté equivocado ...

+1

La pregunta está etiquetada como incrustada, donde la volatilidad es muy típica. La volatilidad en variables automáticas (locales) es significativa, por ejemplo, como contadores de bucle para la implementación de retardo: 'for (volatile unsigned int i = delay; i> 0; --i) {}'. Como el ciclo no hace nada lógico, un optimizador podría eliminarlo si no fuera por 'volátil '. – Gauthier

+1

También es útil para crear, p. una variable de depuración, donde puede escribir en una variable que el programa nunca lee, y tiene la intención de leer el contenido más adelante en un depurador. 'static volatile uint8_t debug_buffer [64];' Como el compilador ve que los valores guardados nunca se vuelven a usar, podría eliminar la escritura. 'volátil' impide eso. – Gauthier

+0

@Gauthier ¡Gracias en consejo! Recuerdo que alguna plataforma incorporada permite detener la ejecución en el acceso a la memoria a cierta dirección para que pueda rastrear fácilmente cualquier cambio en los valores de la variable sin perder el rendimiento de la ejecución al marcarlo como volataile. – gavenkoa

2

volatile significa generalmente uno o más de los siguientes:

  1. la variable puede cambiarse por otro subproceso OS
  2. el flujo normal de ejecución en el programa puede ser interrumpido por una señal y el controlador de señal podría cambiar la variable
  3. el flujo normal de ejecución ejecuta un bucle, la variable está siendo leído dentro del bucle, y la variable se cambia por medio de punto 1 o 2

volatile significa que durante toda la vida útil del programa hay dos (o más) lecturas R1 y R2 de la variable, y algún otro evento que ocurra entre R1 y R2 cambiará la variable fuera del flujo normal de ejecución.


extern significa que la variable se ha definido en alguna otra parte y que el programa está reutilizando esa definición.

-1

Esencialmente, volátil se utiliza para indicar que el valor de una variable se modificará por diferentes subprocesos.

Declarar una variable volátil Java significa:

The value of this variable will never be cached thread-locally: all reads and writes will go straight to "main memory"; 
Access to the variable acts as though it is enclosed in a synchronized block, synchronized on itself. 

Extern significa esencialmente que todos los módulos pueden utilizar la variable definida.

1

No estoy del todo de acuerdo con las respuestas anteriores, así que aquí están mis dos centavos.

Al declarar una variable volátil le está diciendo al compilador que su valor puede cambiar en cualquier momento y que no puede hacer suposiciones sobre el valor de la variable, ni siquiera en dos instrucciones consecutivas (ensamblador). En consecuencia, cualquier uso de la variable debe hacerse accediendo a la variable real y no a un valor en caché.

En el código proporcionado no hay diferencia de comportamiento entre abc ser global, extern o volátil porque if()/else solo evalúa la variable una vez. Hay una diferencia, sin embargo, si se cambia el otro por un segundo si, como en:

if(abc == 3) 
{ 
    printf("abc == 3"); 
} 
if (abc != 3) 
{ 
    printf("abc != 3"); 
} 

Si ABC no se declara volátil, el compilador puede optimizar el segundo caso y sustituirla por una declaración más, en abc consecuencia solo se leería y evaluaría una vez, lo que significa que se ejecutará la primera xor la segunda impresión (pero no ambas y tampoco ninguna).

Si abc IS se declara volátil (no importa si es local, global o extern), el compilador se ve obligado a evaluar abc dos veces porque su valor podría haber cambiado entre medio. Esto significa que se puede ejecutar cualquiera de las dos impresiones, o ambas, o ninguna.

Extern es una historia totalmente diferente. Todo lo que hace es decirle al compilador que la variable se ha definido en otro archivo (cuya dirección se proporcionará en el momento del enlace). Si el compilador puede predecir que el valor de abc no cambiará entre las dos sentencias if (no importa cómo pueda hacerlo el compilador), entonces aún puede optimizar el segundo si está en otro y reducir los dos abc evaluaciones a uno.

Cuestiones relacionadas