¿Por qué el tamaño de la matriz global debe ser una constante entera?

8

En C ++ intenté declarar una matriz global de algún tamaño. Recibí el error:

El conjunto de enlaces no es una constante entera antes del token ']'

Pero cuando declaró una matriz del mismo tipo en la main()función, funciona bien.

¿Por qué hay un comportamiento diferente aquí?

int y=5;
int arr[y];         //When I comment this line it works fine

int main()
{
    int x=5;
    int arr2[x];        // This line doesn't show any error.
}

Editar: Muchos están sugiriendo que esta pregunta es un duplicado del error Obteniendo "el enlace de matriz no es una constante entera antes del token ']' . Pero esa pregunta no responde por qué hay un comportamiento diferente.

Syed Maqthyar
fuente
3
Incluso en main, no es legal, utiliza la extensión VLA.
Jarod42
44
Los límites de todas las matrices, en C ++, deben tener un valor que se conozca durante la compilación. Si dicho código, cuando se coloca en, maines "aceptado" por su compilador: está utilizando la extensión del compilador, que permite la compilación de VLA, incluso si no son compatibles con el estándar C ++.
Algirdas Preidžius
2
no confunda "no hay errores de compilación" con "está funcionando bien". En este caso, "funciona bien" significa que su código se basa en una extensión proporcionada por el compilador no estándar, es decir, está bien pero no es portátil c ++
idclev 463035818
¿Por qué no declarar yy xcomo const? ¿Necesita modificar el valor de yo x? Esperemos que no, porque eso plantea muchas preguntas sobre cuán grande arry arr2debería ser, especialmente con la respuesta al orden de inicialización. (Sugerencia: deberían ser constantes)
Wyck
Compile su programa con --std=c++17(o --std=c++11si es un compilador anterior), y la compilación fallará.
einpoklum

Respuestas:

9

Ambos ejemplos están mal formados en C ++. Si un compilador no diagnostica el último, entonces no se ajusta al estándar.

¿Por qué hay un comportamiento diferente aquí?

Utiliza una extensión de idioma que permite matrices automáticas de longitud de tiempo de ejecución. Pero no permite matrices estáticas de longitud de tiempo de ejecución. Las matrices globales tienen almacenamiento estático.

En caso de que esté utilizando GCC, puede pedirle que se ajuste al estándar utilizando la opción de línea de comando -pedantic. Es una buena idea hacerlo para estar informado sobre los problemas de portabilidad.

eerorika
fuente
4

El tamaño de una matriz debe ser una constante. Puede solucionar esto declarando ycomo const.

const int y=5;
int arr[y]; 

En cuanto a por qué esto funcionó main, g ++ permite una matriz de longitud variable en el alcance del bloque como una extensión. Sin embargo, no es C ++ estándar.

dbush
fuente
0

No deberían usarse ambos, uno funciona porque (como dijo @eerorika) se permiten matrices de longitud automática en tiempo de ejecución, pero las matrices globales deben tener almacenamiento estático.

Si desea declarar una matriz con un tamaño variable (p. Ej., Dada por std :: cin), debería hacer algo similar a:

int x;
std::cin >> x;
const int n = x;
float arr[n];

Pero no podrá configurarlo para que contenga solo ceros con float arr[n] = {0}(si necesita agregar un valor a la matriz, sin estar seguro de haberlo configurado), necesitaría usar un bucle como ese

for(int i = 0; i < n; i++)
{
    arr[i] = 0;
}
Jacob Korba
fuente
1
Su ejemplo todavía está mal formado a pesar de usar const. El tamaño debe ser una expresión constante de tiempo de compilación. Algo que obtienes de la entrada de tiempo de ejecución, por supuesto, no satisface eso.
Eerorika
La afirmación de que "No se deben usar ambos" es inapropiada. Es posible que desee evitar el uso de una matriz de longitud variable para escribir código C ++ portátil. Es posible que desee utilizar una matriz de longitud variable para lograr el objetivo deseado del proyecto a expensas de la portabilidad. Los valores de estos objetivos son subjetivos y circunstanciales, y no se puede decir dónde está el equilibrio para otra persona.
Eric Postpischil
@EricPostpischil Tienes razón, pero cuando usas una variable mutable, puedes cambiarla y por razones de seguridad es mejor mantenerla como constante
Jacob Korba
0

El sistema de tipos de C ++ maneja estas matrices tipo C de una manera que define a arr2partir de su ejemplo de tipo int[5]. Entonces, sí, ¡el número de elementos de la matriz es parte del tipo!

Esto pone algunas restricciones sobre lo que puede usar en la definición de matrices tipo C. Es decir, este número debe tener almacenamiento estático , debe ser inmutable y debe estar disponible en el momento de la compilación .

Por lo tanto, es posible que desee cambiar su código a algo como lo siguiente, que tendrá otra ventaja. Inicializa la matriz de manera adecuada:

int arr2[] = {0, 0, 0, 0, 0};   
salchint
fuente