2011-05-30 15 views
28

Hoy por cierto, de forma incidental definí una matriz bidimensional con el tamaño de una dimensión siendo 0, sin embargo, mi compilador no se quejó. Me encontré con lo siguiente, que afirma que esto es legal, al menos en el caso de gcc:Matriz con tamaño 0

6.17 Arrays of Length Zero

Sin embargo, tengo dos preguntas sobre este uso:

En primer lugar, se considera esto como una buena programación ¿práctica? Si es así, ¿cuándo deberíamos usarlo en el mundo real?

En segundo lugar, la matriz que definí fue bidimensional, con 0 tamaños para una dimensión. ¿Es esto lo mismo que el caso unidimensional? Por ejemplo,

int s[0] 
int s[0][100] 
int s[100][0] 

¿Son todos iguales en la memoria y para el compilador?

EDITAR: Responder a Greg: El compilador que estoy utilizando es gcc 4.4.5. Mi intención para este problema no es dependiente del compilador, sin embargo, si hay algunas peculiaridades específicas del compilador que también serían útiles :)

¡Gracias de antemano!

+0

Dado que ha hecho referencia al compilador en su pregunta, sería útil proporcionar información sobre el compilador particular que le preocupa. – Greg

+1

Compruebe esto http://stackoverflow.com/questions/295027/array-of-zero-length – vasin

+0

Tenga en cuenta que con C++ 11, el tipo 'std :: array' [puede tener un tamaño de 0] (http: //en.cppreference.com/w/cpp/container/array) (pero las matrices normales aún deben tener al menos un elemento). – Cameron

Respuesta

26

En C++ es ilegal declarar una matriz de longitud cero. Como tal, normalmente no se considera una buena práctica, ya que está vinculando su código a una extensión de compilación en particular. Muchos usos de las matrices de tamaño dinámico se reemplazan mejor con una clase de contenedor como std::vector.

ISO/IEC 14882: 2003 8.3.4/1:

Si el constante-expresión (5.19) está presente, deberá ser una expresión constante integral y su valor será mayor que cero .

Sin embargo, puede asignar dinámicamente una matriz de longitud cero con new[].

ISO/IEC 14882: 2003 5.3.4/6:

La expresión en una directa-new-declarador tendrá tipo integral o de enumeración (3.9.1) con un valor no negativo .

+1

Charles no puede entender que se puede asignar dinámicamente una matriz de longitud cero, ¿puede dar más información al respecto? –

+2

@Krishna_Oza Puede hacer esto: 'int * x = new int [0];' y devolverá un puntero, pero desreferenciarlo no está definido, ya que no hay un motivo posible para hacerlo. El compilador podría realizar desreferenciaciones que hacen cualquier cosa, incluido el bloqueo de su programa. – smead

4

que corrió este programa en ideone.com

#include <iostream> 

int main() 
{ 
    int a[0]; 
    int b[0][100]; 
    int c[100][0]; 

    std::cout << "sizeof(a) = " << sizeof(a) << std::endl; 
    std::cout << "sizeof(b) = " << sizeof(b) << std::endl; 
    std::cout << "sizeof(c) = " << sizeof(c) << std::endl; 

    return 0; 
} 

Se dio el tamaño de todas las variables como 0.

sizeof(a) = 0 
sizeof(b) = 0 
sizeof(c) = 0 

Así en el ejemplo anterior, no se asigna memoria para a, o bc.

+0

En respuesta, ¿puede agregar en qué compilador se ejecutó, ya que el enlace que especificó no muestra el código? –

+0

@Krishna_Oza ideone.com usa gcc 5.1 a partir del 2015-10-20, que es uno de los pocos compiladores que admite matrices vacías (que encontré bastante conveniente para pruebas genéricas al pasar matrices de diferentes tamaños a funciones, incluido el vacío) como un caso de prueba válido). –

2

Al compilar su ejemplo con gcc, los tres tienen sizeof 0, así que supongo que todos ellos son tratados por igual por el compilador.

+1

Y eso sería un compilador * error *, no una extensión de proveedor. C++ requiere que todos los objetos deben tener un tamaño de al menos un byte, por lo que obtienen direcciones únicas. –

+0

@Ben Voigt: no es un error en el sentido de que gcc permite explícitamente matrices de longitud cero, como se muestra en el enlace provisto por el póster original. – Kanopus

+0

Es un error. Los proveedores tienen mucha libertad de acción para aceptar código para el cual el estándar no define el comportamiento, pero cuando lo hacen, aún deben seguir las reglas estándar que se apliquen. El estándar requiere que cada objeto tenga una dirección única y un tamaño estrictamente positivo. los subobjetos necesitan una dirección distinta de cada objeto que no sea padre. –

2

Su enlace lo explica todo. Se utilizan como último campo en una estructura cuando la longitud de la estructura no se conoce en el momento de la compilación.Si intenta usarlos en la pila o en medio de otras declaraciones, terminará sobrescribiendo los siguientes elementos.

Cuestiones relacionadas