2011-03-31 28 views
5

Estoy muy a menudo confunden al volver a C por la incapacidad para crear una matriz usando la siguiente pauta de inicialización ...El modificador const en C

const int SOME_ARRAY_SIZE = 6; 
const int myArray[SOME_ARRAY_SIZE]; 

Mi comprensión del problema es que la const el operador no garantiza la const-ness, sino que simplemente afirma que el valor apuntado por SOME_ARRAY_SIZE no cambiará en el tiempo de ejecución. Pero, ¿por qué el compilador no puede asumir que el valor es constante en el momento de la compilación? Dice 6 allí mismo en el código fuente ...

Creo que me falta algo fundamental en mi comprensión fundamental de C. Alguien me ayude aquí. :)

[ACTUALIZACIÓN] Después de leer un poco más sobre C99 y arreglos de longitud variable, creo que entiendo esto un poco mejor. Lo que intentaba crear era una matriz de longitud variable: const no crea una constante de tiempo de compilación, sino más bien una constante de tiempo de ejecución. Por lo tanto, estaba inicializando una matriz de longitud variable, que solo es válida en C99 en un alcance de función/bloque. Una matriz de longitud variable en el alcance del archivo es imposible ya que el compilador no puede asignar una dirección de memoria fija a una matriz ilimitada. [/ UPDATE]

+0

Por favor, aclare si está preguntando acerca de tales declaraciones en el alcance local o alcance global, ya que la respuesta es diferente en cada caso. –

+0

Disculpa, esta es una declaración con ámbito global. – mmccomb

Respuesta

5

Bueno, en C++ la semántica es un poco diferente. En C++ tu código funcionaría bien. Debe distinguir entre 2 cosas, const y constant expression. Const significa simplemente, como usted describió, que el valor es de solo lectura. expresión constante, por otro lado, significa que el valor es tiempo de compilación conocido y es una constante en tiempo de compilación. La semántica de const en C es siempre del primer tipo. Las únicas expresiones constantes en C son literales, por eso #define se usa para ese tipo de cosas.

En C++, sin embargo, cualquier objeto const inicializado con una expresión constante es en sí mismo una expresión constante.

No sé exactamente por qué esto es así en C, es sólo la forma en que es

4

El problema es que la sintaxis del lenguaje exige un valor entero entre []. SOME_ARRAY_SIZE sigue siendo una variable (incluso si le dijo al compilador que nadie puede variarlo)

+0

Entonces, ¿es una deficiencia en la implementación del compilador? Como Paul R comentó en su respuesta, la sintaxis anterior ahora es compatible con las versiones más recientes de gcc ... – mmccomb

+0

Creo que su compilador es muy exigente con respecto a cómo interpreta los estándares de C. –

1

Puede hacer esto en C99, y algunos compiladores anteriores a C99 también tienen soporte para esto como una extensión de C89 (por ejemplo, gcc) Si está atascado con un compilador antiguo que no tiene compatibilidad con C99 (por ejemplo, MSVC), tendrá que hacerlo a la manera old skool y usar #define para el tamaño de la matriz.

Tenga en cuenta que los comentarios anteriores se aplican solo a tales declaraciones en el ámbito local (es decir, variables automáticas). C99 aún no permite tales declaraciones en el alcance global.

+1

No, C99 tampoco lo admite. C++ sí, sin embargo. – Lindydancer

+0

@Lindydancer: OK - para aclarar - C99 permite esto dentro del alcance local (es decir, con variables automáticas) pero no en el alcance global - He actualizado la respuesta en consecuencia. –

+0

La interfaz EDG C99 emite un error para: 'void foo (void) {const int X = 6; const int myArray [X] = {100}; bar (myArray); } ' Sin embargo, podría estar equivocado así que publique un contador de ejemplo o una referencia al estándar C99. – Lindydancer

0

que acabo de hacer una prueba muy rápida con mi Xcode y el archivo C Objetivo actualmente que tenía abierta en mi máquina y poner esto en el archivo .m:

const int arrs = 6; 
const int arr[arrs]; 

Esto compila sin ningún problema.

+0

Debería funcionar dentro de un bloque, pruébelo en el alcance del archivo ... – mmccomb

+0

estaba en el alcance del archivo. –

2

La palabra clave const es básicamente una indicación de sólo lectura. En realidad, no indica que el valor subyacente no cambiará, aunque ese sea el caso en su ejemplo.

Cuando se trata de punteros, esto es más claro:

void foo(int const * p) 
{ 
    if (*p == 100) 
    { 
    bar(); 
    /* Here, the compiler can not assume that *p is 100 */ 
    } 
} 

En este caso, un compilador no se debe aceptar el código en su ejemplo, ya que requiere el tamaño de la matriz para que sea constante. Si lo acepta, el usuario podría tener más problemas al portar el código de un compilador más estricto.

+0

Buen ejemplo :) Ver otro caso de uso para el operador hace las cosas mucho más claras – mmccomb