En C, ¿por qué no se puede utilizar una variable const como un inicializador de tamaño de matriz?

En el siguiente código, const int no se puede usar como tamaño de matriz:

const int sz = 0; typedef struct { char s[sz]; } st; int main() { st obj; strcpy(obj.s, "hello world"); printf("%s", obj.s); return 0; } 

En C, una variable const calificada no es una expresión constante 1 . Una expresión constante es algo que se puede evaluar en tiempo de comstackción: un literal numérico como 10 o 3.14159 , un literal de cadena como "Hello" , una expresión sizeof , o alguna expresión compuesta de la misma forma como 10 + sizeof "Hello" .

Para las declaraciones de matriz en el ámbito del archivo (fuera del cuerpo de cualquier función) o como miembros de union tipos de struct o union , la dimensión de la matriz debe ser una expresión constante.

Para auto matrices auto (matrices declaradas dentro del cuerpo de una función que no son static ), puede usar una variable o expresión cuyo valor no se conoce hasta el tiempo de ejecución, pero solo en C99 o posterior.


  1. C ++ es diferente en este sentido: en ese lenguaje, una variable const calificada cuenta como una expresión constante.

Esto se debe a que en C const realmente significa solo lectura . Cotizando C Preguntas frecuentes 1.18 y 1.19 :

El calificador const realmente significa “ solo lectura ”; un objeto así calificado es un objeto en tiempo de ejecución al que no se puede (normalmente) asignar. Por lo tanto, el valor de un objeto cualificado constantemente no es una expresión constante en el sentido completo del término, y no se puede utilizar para dimensiones de matriz, tags de casos y similares. (C es diferente a C ++ a este respecto). Cuando necesite una verdadera constante de tiempo de comstackción, use un preprocesador #define (o quizás una enumeración).

Referencias: ISO Sec. 6.4 Secciones de H&S. 7.11.2,7.11.3 pp. 226-7

Hay dos maneras de lidiar con esto:

  1. Use #define lugar de const
  2. Use enum { sz = 12 };

De una manera muy simple porque el comstackdor debe conocer la dimensión de la matriz en el momento de la comstackción y, como puede inicializar la const variable en el tiempo de ejecución, no puede hacerlo. Por lo tanto, el tamaño de las matrices declaradas estáticamente debe ser una expresión constante y una const variable no lo es. Para expresiones constantes , debe usar una macro ( #define ) o enum . Eso está explícitamente para su caso (en el scope del archivo) y si utiliza un estándar mínimo de c99 .