2009-11-07 8 views
11

Tengo un problema al inicializar una matriz cuyo tamaño se define como const externo. Siempre he seguido la regla de que las variables globales deben declararse como extern en los archivos de encabezado y sus definiciones correspondientes deben estar en uno de los archivos de implementación para evitar errores de redeclaración de variables. Este enfoque funcionó bien hasta que tuve que inicializar una matriz con cuyo tamaño se define como una const externa. Aparece un error que se espera una expresión constante. Sin embargo, si intento asignar un valor a la variable const, el compilador se queja correctamente de que no se puede asignar un valor a una variable constante. Esto realmente prueba que el compilador ve la variable como una constante. ¿Por qué entonces se informa un error cuando trato de declarar una matriz del mismo tamaño?Declaración de una matriz cuyo tamaño está declarado como const externo

¿Hay alguna forma de evitar esto sin usar #define? También me gustaría saber el motivo de este error.

Package.h:

#ifndef PACKAGE_H 
#define PACKAGE_H 

extern const int SIZE; 

#endif 

Package.cpp:

#include "Package.h" 

const int SIZE = 10; 

foo.cpp:

#include "Package.h" 

int main() 
{ 
    // SIZE = 5; // error - cannot assign value to a constant variable 
    // int Array[SIZE]; // error - constant expression expected 
    return 0; 
} 
+0

Puede aplicar sangría al código con cuatro espacios para formatearlo. – Thomas

Respuesta

16

La constante es externa, por lo que se define en otra unidad de compilación (archivo .o). Por lo tanto, el compilador no puede determinar el tamaño de su matriz en el momento de la compilación; hasta el momento del enlace no se sabe cuál será el valor de la constante.

3

Bueno, se ve a la variable como const calificó, no como una expresión constante.

2

Creo que el problema aquí es que si declara su variable como extern, puede estar en un módulo diferente (archivo .o) o incluso en una biblioteca dinámica (.dll/.so). Esto significa, por supuesto, que el compilador podría no ser capaz de resolver el contenido de la variable en tiempo de compilación, por lo que se niega a usar el valor en el que se requiere una const.

Mi opinión es que está perfectamente bien no usar extern aquí y declararlo directamente en el archivo de encabezado, ya que es un valor int de todos modos que se insertará cuando se use en cualquier parte del código. Usualmente uso extern const solo cuando trabajo con cadenas, ya que quiero asegurarme de que solo se genere una instancia de la cadena en tiempo de ejecución.

3

Dado que es solo un int, eliminaría el extern y lo convertiría en una definición en lugar de una declaración. La razón por la que digo esto es que a pesar de que este enfoque coloca una instancia separada del entero en cada archivo fuente que incluye el encabezado, me imagino que la mayoría de los compiladores optimizarán su uso. De hecho, es imposible para el compilador optimizar su uso si no lo hace, por lo que no se optimizará a partir de expresiones aritméticas simples.

Como está declarado const tendrá un enlace interno y por lo tanto no obtendrá ningún problema de símbolo definido de forma múltiple al hacerlo de esta manera.

+0

Gracias. Creo que lo entiendo ahora. Pero, ¿por qué este enfoque no funciona para const punteros. Si defino const char * FILE_NAME = "Log.txt" en el archivo de encabezado e incluyo el archivo de encabezado en varios archivos de origen, sigo recibiendo un error de enlace. No obtengo un error para la declaración const char FILE_NAME [] = "Log.txt " – psvaibhav

+0

@psvaibhav: Eso no funcionará porque' const char * 'declara que el puntero es un puntero-a-const y _not_ un puntero constante. Lo que necesitas es un' const' extra después del '*' para hacer el puntero en sí constante es decir 'const char * const – Troubadour

Cuestiones relacionadas