¿”Int size = 10″ produce una expresión constante?

El siguiente código se comstack bajo gcc 4.8 y Clang 3.2:

int main() { int size = 10; int arr[size]; } 

8.3.4 / 1 del Estándar C ++ dice que el tamaño de una matriz debe ser una expresión constante integral, cuyo size no parece ser. ¿Es esto un error en ambos comstackdores, o me estoy perdiendo algo?

La última CTP de VC ++ rechaza el código con este interesante mensaje:

 error C2466: cannot allocate an array of constant size 0 

La parte interesante es cómo parece pensar que el size es cero. Pero al menos rechaza el código. ¿No deberían GCC y Clang hacer lo mismo?

Se trata de arrays de longitud variable o VLA que es una característica C99 , pero gcc y clang lo admiten como una extensión en C ++, mientras que Visual Studio no lo hace . Entonces, Visual Studio se adhiere al estándar en este caso y es técnicamente correcto. Para no decir que las extensiones son malas, el kernel de Linux depende de muchas extensiones de gcc , por lo que pueden ser útiles en ciertos contextos.

Si agrega el indicador -pedantic , tanto gcc como clang le advertirán sobre esto, por ejemplo, gcc dice ( -pedantic en vivo ):

 warning: ISO C++ forbids variable length array 'arr' [-Wvla] int arr[size]; ^ 

El uso del -pedantic-errors hará que esto sea un error. Puede leer más acerca de las extensiones en estos documentos . Estándares de idioma admitidos por GCC y clangs . Sección de compatibilidad de idiomas .

Actualizar

El borrador del estándar de C ++ cubre lo que es una expresión de constante integral en la sección 5.19 Expresiones constantes, párrafo 3 y dice:

Una expresión constante integral es una expresión del tipo de enumeración integral o no codificado, convertida implícitamente en un valor prve, donde la expresión convertida es una expresión constante central. […]

No es intuitivamente obvio al leer esto cuáles son todas las posibilidades, pero las Pautas de encoding de Boost para expresiones constantes integrales hacen un gran trabajo al respecto.

En este caso, dado que está inicializando el size con un literal que usa const, sería suficiente para convertirlo en una expresión de constante integral (consulte [expr.const] p2.9.1 ) y también devolver el código a ser C ++ estándar:

 const int size = 10; 

usar constexpr también funcionaría:

 constexpr int size = 10; 

Probablemente sería útil leer Diferencia entre constexpr y const .

A modo de referencia, la sección equivalente al párrafo 1 del párrafo 8.3.4 en el proyecto de norma C99 sería la sección 6.7.5.2 párrafo 4 de los 6.7.5.2 matriz ( énfasis mío ):

Si el tamaño no está presente, el tipo de matriz es un tipo incompleto. Si el tamaño es * en lugar de ser una expresión, el tipo de matriz es un tipo de matriz de longitud variable de tamaño no especificado, que solo se puede usar en declaraciones con scope de prototipo de función; 124) tales matrices son, sin embargo, tipos completos. Si el tamaño es una expresión constante entera y el tipo de elemento tiene un tamaño constante conocido, el tipo de matriz no es un tipo de matriz de longitud variable; de lo contrario, el tipo de matriz es un tipo de matriz de longitud variable .