2009-12-08 16 views
7

Algunas veces necesitamos declarar previamente una variable estática y luego usarla. Pero el nombre de la variable de esta declaración puede estar equivocado, y el compilador no puede detectarlo, ¡vaya!Cómo declarar una variable estática pero no definirla

Ejemplo:

/* lots of codes */ 
static some_type some_name; /* pre-declaration */ 
          /* but it may define "some_name" */ 
/* use some_name */ 

/* lots of codes */ 

static some_type someName = initialization; /* definition */ 
/* use someName */ 

/* lots of codes */ 

"some_name" y "somename" son diferentes, utilizamos una variable equivocado en el comenzar. Si la declaración previa a la declaración no define nada, el compilador detectará el error.

Entonces, ¿cómo declarar una variable estática pero no definirla? ¿Cómo puedo cambiar la pre declaración a una nueva que hace que el compilador pueda detectar nombres incorrectos?

+4

estático significa que está cargado en tiempo de compilación. ¿Por qué no quieres inicializarlo? – Woot4Moo

+1

Woot4Moo: Hacer que una variable global sea "estática" en C significa que no está visible fuera de la "unidad de compilación" actual, generalmente un archivo .c y todos sus encabezados. Todas las variables globales que no son 'externas' tienen espacio asignado en tiempo de compilación. – Anton

Respuesta

9

gcc dará una advertencia en el caso que has descrito:

./x.c:3010: warning: 'someName' defined but not used 

Solución haga lo que está haciendo actualmente, pero no ignore las advertencias del compilador;)

Edición:

Con su pregunta actualizada: No, no creo que haya una forma de declarar simplemente una variable estática (sin definirla también).

La solución común es solo asegurarse de que todas las variables de ámbito global se declaran una sola vez, con un inicializador si lo necesitan.

+0

"someName" también se está utilizando, he cambiado un poco mi publicación, gracias. –

8
static some_type some_name; /*definition */ 

La variable estática some_name se ha inicializado por 0; es la definición, no solo una declaración.

IMO, una variable estática no se puede simplemente declarar en C utilizando el especificador externo ya que su enlace siempre es interno.

+1

No creo que estés usando "IMO" correctamente.Eso no suena como una opinión. –

+1

Es la opinión de Prasoon; también se alinea con el estándar, por lo que su opinión es correcta (de acuerdo con el estándar). –

0

¿Necesita declarar previamente la variable? De lo contrario, ponga el inicializador en la única declaración. Si su inicializador no es una constante (que requeriría C++, no C, IIRC), entonces puedo entender por qué necesita declararlo antes de algunas funciones que lo usan. Pero entonces todo lo que necesita para el inicializador podría pre-declararse antes de él.

Así que ponga sus variables constantes y estáticas arriba en la parte superior de cada archivo, para que su inicializador de la estática pueda aparecer justo después de las constantes. Entonces no necesita una línea de inicialización separada.

En cualquier otro caso, caf's right: Vale la pena obtener su código para compilar con gcc solo para obtener el beneficio de sus advertencias. Lo hice para g ++ para una interfaz gráfica de usuario de MFC en C++. (compilar, no ejecutar!)

AFAIK C no tiene forma de escribir una definición débil que producirá un error si no hay una definición con un inicializador más adelante. Siempre hay un 0 implícito, ya que la variable va en la sección BSS.

-1

Si entiendo su problema tal vez su solo no lo enfrenta de la manera correcta.

¿No sería mejor con extern SomeType someVar_; que dice a su programa, sé que esta variable se conocerá, pero no quiero decir lo que es ahora.

Puede, por lo tanto, en un archivo separado declarar la variable dicen

static SomeType SomeVar_;

En su archivo, poner

extern SomeType SomeVar_

Y que poner la inicialización donde desee.

+1

Eso causará un error del enlazador, ya que la definición 'estática' tiene un enlace interno y no puede ser alcanzado por el archivo donde se declara usando' extern'. –

2

Un poco de historia:

Como otros han señalado, son variables estáticas tienen vinculación interna, lo que significa que sólo se pueden utilizar en la misma "unidad de compilación" o archivo de origen. Eso significa que no puede declararlo en un archivo de encabezado, asignarle un valor en una unidad de compilación y esperar que ese valor aparezca en otro.

Cuando inicializa una variable global (estática o no), el compilador simplemente coloca el valor inicial en el archivo ejecutable en la ubicación de memoria asignada para la variable. En otras palabras, siempre tiene un valor inicial. Por supuesto, siempre puede anular el valor más tarde mediante el uso de una declaración de asignación.

Sugerencias:

Si realmente no se conoce el valor de la variable en tiempo de compilación, entonces deben asignar de forma dinámica en su función de inicialización.

static some_type some_variable; /* = 0 by default */ 

/* some code */ 

void MyInitializations() 
{ 
    some_variable = some_value; 
} 

Si desea declarar la variable en un solo lugar, dicen que un archivo de cabecera, y lo definen en un archivo de origen, entonces debe usar una declaración 'extern' que le dice al compilador que no se preocupe por donde el variable es. El vinculador encontrará la ubicación de la variable de forma similar a como encuentra una función en otro archivo y completa la dirección.

Cabecera:

extern some_type some_variable; 

archivo Fuente 1:

void UseSomeVariable() 
{ 
    x = some_variable; 
} 

archivo Fuente 2:

some_type some_variable = some_value; 

/* possible also uses some_variable */ 

Si lo que desea es declarar la variable en un lugar y definirlo en otra, no use la palabra clave "estática". La desventaja de esto es que no puede usar la misma variable global en diferentes unidades de compilación (archivos .c) y no puede usarla en un archivo de encabezado.

3

No es posible crear una declaración no definitoria (es decir, "pre-declarar" en su terminología) de un objeto con enlace interno en lenguaje C.

Lo más cerca que puede llegar a eso es una definición tentativa , que es lo que tiene en su ejemplo. Pero en el caso de una definición tentativa de error tipográfico producirá implícitamente una definición independiente, no un error de enlazador.

Cuestiones relacionadas