usar - variable static c
¿Por qué no se vincula externamente a una variable estática? (4)
El propósito completo y completo de la static
es declarar que una variable es privada al archivo fuente en el que se declara . Por lo tanto, está haciendo precisamente su trabajo para evitar una conexión desde un externo.
Tenga en cuenta que hay cuatro tipos de definición de variable de alcance de archivo:
-
int blah = 0;
- blah se define en este archivo y se puede acceder desde otros archivos. Las definiciones en otros archivos son duplicados y darán lugar a errores. -
extern int blah;
- bla debe definirse en otro lugar y se hace referencia desde este archivo. -
int blah;
- Este es el equivalente moral de FORTRANCOMMON
. Puede tener cualquier número de estos en archivos, y todos ellos se resuelven mediante el enlazador a unint
compartido. (*) -
static int blah;
(opcionalmente con un inicializador) - Esto es estático. Es completamente privado a este archivo. Los archivos externos no lo pueden ver en otros archivos, y puede tener muchos archivos diferentes que todos declaranstatic TYPE blah;
, y todos ellos son diferentes .
Para los puristas en la audiencia: ''archivo'' = unidad de compilación .
Tenga en cuenta que las funciones estáticas internas (no en el ámbito del archivo) están aún más ajustadas: si dos funciones declaran static int bleh = 0;
incluso en el mismo archivo, no están relacionados.
(*): para aquellos que no estén familiarizados: en el patrón habitual, una unidad de compilación tiene que definir una variable global, y otras pueden hacer referencia a ella. ''Vive'' en esa unidad de compilación. En el caso (3), arriba, ningún archivo (o todos los archivos) lo define. Si dos archivos dicen int blah = 0;
, el enlazador se quejará de múltiples definiciones. Si dos archivos dicen int blah;
el enlazador crea alegremente un solo int
global y hace que todo el código se refiera a él.
¿Por qué extern int n
no se compila cuando n se declara (en un archivo diferente) static int n
, pero funciona cuando se declara int n
? (Ambas declaraciones estaban en el alcance del archivo).
Básicamente, ¿por qué int n
en el alcance del archivo no es lo mismo que static int n
en el mismo alcance? ¿Es sólo en relación con extern? Si es así, ¿qué pasa con extern me estoy perdiendo?
En el estándar C, hay dos ámbitos para las variables declaradas fuera de una función. Una variable static
solo es visible dentro de la unidad de compilación (es decir, el archivo) que la declaró, y las variables no estáticas son visibles en todo el programa. Una declaración extern
dice que la ubicación de la variable aún no se conoce, pero será ordenada por el enlazador; es compatible con variables no estáticas, ¡pero la extern static
es solo una locura!
Por supuesto, en la práctica hay otras visibilidades en estos días. En particular, ahora hay niveles de alcance entre el de un único archivo fuente y un programa completo; el nivel de una sola biblioteca compartida es útil (configurable a través de mecanismos como los atributos de la función GCC). Pero eso es solo una variación del tema de las variables no estáticas; static
mantiene la misma interpretación que tenía antes.
Según la documentación de MSDN:
Al modificar una variable, la palabra clave estática especifica que la variable tiene una duración estática (se asigna cuando el programa comienza y se desasigna cuando finaliza el programa) y la inicializa a 0 a menos que se especifique otro valor. Al modificar una variable o función en el alcance del archivo, la palabra clave estática especifica que la variable o función tiene un enlace interno (su nombre no es visible desde fuera del archivo en el que se declara).
http://msdn.microsoft.com/en-us/library/s1sb61xd(v=vs.80).aspx : junio de 2013
iv.c: 2: 1: error: varias clases de almacenamiento en los especificadores de declaración extern static int i; ^
Eso es lo que conseguimos al intentar externar una variable estática. Declarar extern estática int i; - es análogo a la declaración float int i; No puedes tener flotar y aparecer en la misma declaración, ¿verdad? Del mismo modo, no puede tener extern y static en la misma declaración.