2012-03-13 17 views
9
#include <stdio.h> 

static i = 5; 

int main() 
{ 
extern int i; 
printf("%d\n",i); 
return 0; 
} 

¿Alguien puede dar cualquier caso de uso para declarar una variable estática como extern dentro de un bloque de funciones?¿Cuál es el uso de declarar una variable estática como extern dentro de una función?

NUEVO: ¿Por qué no se permite?

int main() 
{ 
static i = 5; 
extern int i; 
printf("%d\n",i); 
return 0; 
} 
+3

Porque 'i' es externo o local, no puede ser ambos. – Till

+0

no permitido? Su segundo fragmento de código funciona perfectamente bien en mi gcc (mingw) –

+0

Estoy usando gcc 4.1.2 20080704 (Red Hat 4.1.2-51) y me sale el siguiente error: file1.c: En la función âmainâ: file1.c : 6: error: declaración externa de âa sigue la declaración sin vinculación file1.c: 5: error: la definición anterior de âiâ estaba aquí – Bruce

Respuesta

8

Esto es útil cuando se necesita para acceder a una variable que reside dentro de otra unidad de traducción, sin exponer la variable externa a nivel mundial (por algunas razones, como la colisión de nombres, o que la variable del no debería ser directamente accedido, por lo que static se usó para limitar su alcance, pero ese encabezado de TU aún necesita acceso).

A modo de ejemplo, digamos que tenemos una unidad de traducción foo.c, que contiene:

//foo.c 
static int i = 0; 

i No se debe cambiar o directamente acceder sin entrar en foo.c, sin embargo, a lo largo de foo.h viene requiriendo acceso a i para una función en línea, pero i no debe exponerse a ninguna unidad de traducción utilizando foo.h, por lo que podemos usar extern a nivel funcional, para exponerlo solo durante el alcance de IncI, la función en línea que requiere el uso de i:

//foo.h 
inline void IncI(int val) 
{ 
    extern int i; 
    i += val; 
} 

Su segundo ejemplo es 'anulado' porque el compilador piensa que usted está tratando de unir dos variables diferentes para el mismo nombre de símbolo, es decir: se crea la static i en el ámbito local, pero las búsquedas para el extern int i en ámbito global, pero no lo encuentra, porque static i como en el alcance de la función. un compilador más inteligente solo arreglaría el enlace al static i, si esto sigue los estándares que yo no sabría.


Ahora que tengo un C standards document a trabajar a partir de (la culpa es mía lo sé ...), podemos ver lo que la postura oficial es (en C99):

6.2.2 Linkages of identifiers

Section 3:

If the declaration of a file scope identifier for an object or a function contains the storageclass specifier static, the identifier has internal linkage.

Section 4:

For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.

así, porque static causará un enlace interno, el extern llevará ese enlace al alcance actual. también hay una nota que indica que esto puede causar escondite de variables:

23) As specified in 6.2.1, the later declaration might hide the prior declaration.

+2

¿Puede darnos un ejemplo de código, por favor – Bruce

+0

Entonces, ¿cuál es el punto de una estática global? – pezcode

+0

@pezcode: 'static' se puede usar para restringir la visibilidad de un objeto a una unidad de traducción, pero un encabezado con una función' inline' podría necesitar acceso a la variable estática, por lo tanto, el extern en el nivel de función entra en juego, como la función puede acceder a la variable sin cambiar 'globalmente' la visibilidad de la variable estática – Necrolis

0

En el segundo caso, le está diciendo al compilador que tiene una estática (local) variable de i y otro (global) Variable i que se define en algún otro lugar.

+0

¿por qué funcionó en el primer caso? – Bruce

+0

porque en el primer caso el 'static i = 5' estaba fuera del bloque de código, es decir. externo. – len

+0

Creo que es porque cuando escribimos static int i = 5 dentro de una función no tiene ningún vínculo. Sin embargo, cuando está escrito afuera tiene un enlace interno. – Bruce

Cuestiones relacionadas