tipos - ¿Se permite el operador de coma en una expresión constante en C++ 11?
variables y constantes en c++ (2)
En el proceso de responder a esta pregunta en SO para C ++ 11, me di cuenta de que en C ++ 03 (así como en C) el uso del operador de coma está explícitamente prohibido en una expresión constante .
El párrafo 5.19 / 1 de la norma C ++ 03 sobre expresiones constantes dice:
[...] En particular, excepto en tamaño de expresiones, funciones, objetos de clase, punteros o referencias no se utilizarán, y no se utilizarán operadores de asignación, incremento, disminución, llamada de función o coma .
En C ++ 11, sin embargo, la última parte que menciona al operador de coma parece haber desaparecido. Y mientras que el párrafo 5.19 / 2 del Estándar C ++ 11 especifica claramente que las expresiones de llamada de asignación, incremento, decremento y función no constexpr
no aparecerán como constexpr
de una expresión constante , el uso del operador de coma no Parece que ya está prohibido.
Por ejemplo, el siguiente programa compila bien en GCC 4.7.2 y Clang 3.3 con std=c++11
(aparte de las advertencias del compilador que dicen que el operador de coma no tiene efecto y que las variables x
y arr
no se utilizan):
int main()
{
constexpr int x = (0, 42);
int arr[(0, 42)];
}
Sin embargo, debe decirse que incluso el siguiente programa compila bien con la -std=c++03
(ambas en Clang y GCC), que claramente no es correcta, dada la cita anterior del Estándar C ++ 03:
int main()
{
int arr[(0, 42)];
}
PREGUNTA:
¿Hay alguna diferencia entre C ++ 03 y C ++ 11 en cuanto a si se permite o no el operador de coma en una expresión constante, o me falta algo?
Como una pregunta adicional (no constructiva), me interesaría saber por qué el operador de coma no se puede usar en una expresión constante en C ++ 03.
Sin embargo, debe decirse que incluso el siguiente programa compila bien con la opción -std = c ++ 03 (ambas en Clang y GCC), que claramente no es correcta, dada la cita anterior de la norma C ++ 03
No tan rapido. También debe usar -pedantic
(o -pedantic-errors
) para que Clang y GCC apliquen estrictamente las reglas de C ++ 03. Con eso, el tronco de GCC dice:
<stdin>:1:16: error: array bound is not an integer constant before ‘]’ token
y el tronco de Clang dice:
<stdin>:1:19: error: variable length arrays are a C99 feature [-Werror,-Wvla-extension]
void f() { int arr[(0, 42)]; }
^
Como se nota, este código es válido en C ++ 11. Sin embargo, las comas de nivel superior aún no son válidas en C ++ 11, porque una expresión constante en la gramática de C ++ 11 es un tipo de expresión condicional (donde no se permite una coma de nivel superior). Así:
int arr[0, 42];
Todavía está mal formado.
Sí, creo que este es un cambio entre C ++ 03 y C ++ 11. Creo que se hizo más o menos por la razón a la que alude: 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ó de la regla en C (C90, §6.4):
Las expresiones constantes no contendrán operadores de asignación, incremento, decremento, función-llamada o coma, excepto cuando estén contenidas dentro del operando de un operador sizeof .
En cuanto a por qué el operador de coma estaba prohibido en expresiones constantes en C, solo puedo especular. Mi estimación inmediata sería asegurar que una definición como:
int x[2, 5];
... sería rechazado en lugar de dejar al usuario con la creencia errónea de que había definido una matriz de elementos de 2x5, cuando (si se permitía un operador de coma allí) realmente había definido x
con solo 5 elementos.