2011-06-08 12 views
7

Al tratar de explicar a alguien por qué una matriz estática de C++ no podría por tamaño dinámico, encontré gcc en desacuerdo conmigo. ¿Cómo se compila el siguiente código, dado que la dimensión argc de matriz no se conoce en tiempo de compilación?C++ rompecabezas de matriz estática de tamaño dinámico

#include <iostream> 
int main(int argc, char* argv[]) { 
    int array[argc]; 
    for(int i = 0; i < argc; i++) array[i] = argv[i][0]; 
    for(int i = 0; i < argc; i++) std::cout << i << ": " << char(array[i]) << std::endl; 
    //for(int i = 0; i < 100; i++) { std::cout << i << " "; std::cout.flush(); array[i] = 0; } 
    return 0; 
} 

He probado esto con gcc 4.2.1, y que se especifica -Wall, sin conseguir siquiera una mirada sucia del compilador. Si elimino el último ciclo, obtengo una segfault cuando lo asigno a array [53].

había colocado previamente matrices de guardia antes y después de la declaración de gama, y les había llenado con ceros, seguro de que el programa debe ser destrozando parte de su pila, pero gcc reordenado las variables en la pila, de manera que No pude observar ninguna corrupción de datos.

Obviamente, no estoy tratando de hacer que este código "funcione". Solo intento entender por qué gcc incluso cree que puede compilar el código. Cualquier sugerencia o explicación sería muy apreciada.

Actualización: ¡Gracias a todos por sus útiles y ridículamente rápidas respuestas!

+0

permitido por c99 pienso: http://bytes.com/topic/c/answers/770297-c99-dynamic-array – Kevin

+3

El otro problema básico es que está utilizando un compilador para probar si algo es posible en un idioma. Puede especificar un estándar en gcc y puede solicitar una conformidad estricta con el estándar ('-pedantic'?), pero no lo ha hecho, y por lo tanto está permitiendo extensiones de compilador. –

Respuesta

3

Estos se conocen como matrices de longitud variable (disponibles desde C99) y solo se pueden declarar como variables automáticas; intente poner static en el frente y el compilador lo rechazará. Solo implica incrementar el puntero de la pila con una variable en lugar de un desplazamiento constante, no más que eso.

Antes de la introducción de matrices de longitud variable, la asignación de objetos de tamaño variable en la pila se realizó con la función alloca.

2

Los arreglos basados ​​en pila de tamaño variable son una extensión de G ++ y son perfectamente legítimos allí. Sin embargo, no son Estándar. Las matrices basadas en pila pueden ser de tamaño variable en la mayoría de las implementaciones, pero el estándar no exige esto.

2

Las matrices en C++ no se pueden dimensionar excepto mediante el uso de una expresión constante. Las matrices dimensionadas a través de un non-const son parte de C99 o una horrible extensión que nos ha sido impuesta por GCC. Puede deshacerse de la mayor parte de la basura de GCC utilizando el indicador -pedantic cuando compila el código C++.

+0

¿Por qué crees que es una característica horrible? Le permite usar el espacio de pila disponible de manera más eficiente al asignar tanto espacio como necesite. –

+0

@Blagovest Um, ¿quieres decir que usar arreglos basados ​​en pila normal sí? Es basura, y muchos en la comunidad C (y * todos * en la comunidad C++) piensan lo mismo. Además, * nunca * será parte de C++, por lo que es un problema de portabilidad. –

6

Eso es Variable Length Array, que es parte del estándar C99. Sin embargo, no es parte de C++.

También puede utilizar la función alloca, que tampoco es C++ estándar, pero es ampliamente soportado:

int main(int argc, char* argv[]) 
{ 
    int* array = (int*) alloca(argc * sizeof(int)); 
    array[0] = 123; 
    // array automatically deallocated here. Don't call free(array)! 
} 
Cuestiones relacionadas