Tenemos la respuesta a esta cuestión, o por lo menos eso creemos. Si continuas con dudas puedes dejarlo en el apartado de comentarios, que con gusto te responderemos
Solución:
-
Sí, creo que esto es un cambio entre C++03 y C++11. Creo que se hizo más o menos por la razón a la que aludes: que no hay una razón particularmente buena por la que un operador de coma no pueda ser parte de una expresión constante.
-
Creo que la regla en C++03 se originó a partir de la regla en C (C90, §6.4):
Las expresiones constantes no deben contener operadores de asignación, incremento, decremento, llamada de función o coma, excepto cuando están contenidos dentro del operando de un tamaño de operador.
En cuanto a por qué se prohibió el operador de coma en expresiones constantes en C, solo puedo especular. Mi suposición inmediata sería asegurar que una definición como:
int x[5, 2];
…sería rechazado. Si estuviera permitido, podría llevar al programador a creer erróneamente que había definido un elemento 5×2 array (para un total de 10 elementos), cuando (si se permitiera un operador de coma allí) realmente había definido x
con sólo 2 elementos (y el 5
fue efectivamente ignorado por completo).
En cuanto a por qué el comité de C++ consideró que este es un riesgo más aceptable que el comité de C, supongo que se reduce a una situación bastante simple: C casi no ofrece ninguna alternativa, por lo que las matrices se usan bastante. C++, por otro lado, proporciona tanto std::array
y std::vector
dejando muy pocas situaciones en las que haya muchas razones para usar un “crudo” arraypor lo que es mucho menos probable que surja el problema.
Sin embargo, debe decirse que incluso el siguiente programa compila bien con la opción -std=c++03 (tanto en Clang como en GCC), lo que claramente no es correcto, dada la cita anterior del estándar C++03
No tan rapido. Necesitas usar también -pedantic
(o -pedantic-errors
) para que Clang y GCC apliquen estrictamente las reglas de C++03. Con eso, el baúl de GCC dice:
:1:16: error: array bound is not an integer constant before ‘]’ token
y Clang Trunk dice:
:1:19: error: variable length arrays are a C99 feature [-Werror,-Wvla-extension]
void f() int arr[(0, 42)];
^
Como observa, este código es C++11 válido. Sin embargo, nivel superior las comas aún no son válidas en C++11, porque un expresión-constante en la gramática C++11 es una especie de expresión condicional (donde no se permite una coma de nivel superior). Por lo tanto:
int arr[0, 42];
todavía está mal formado.
Si te sientes incitado, eres capaz de dejar un ensayo acerca de qué te ha impresionado de esta división.