Recogí esto en una de mis breves incursiones a reddit:
http://www.smallshire.org.uk/sufficientlysmall/2009/07/31/in-c-throw-is-an-expression/
Básicamente, el autor señala que en C ++:
throw "error"
es una expresion. En realidad, esto se explica con bastante claridad en el estándar C ++, tanto en el texto principal como en la gramática. Sin embargo, lo que no está claro (al menos para mí) es ¿cuál es el tipo de expresión? Supuse " void
", pero un poco de experimentación con g ++ 4.4.0 y Comeau produjo este código:
void f() {
}
struct S {};
int main() {
int x = 1;
const char * p1 = x == 1 ? "foo" : throw S(); // 1
const char * p2 = x == 1 ? "foo" : f(); // 2
}
Los compiladores no tuvieron ningún problema con // 1 pero se burlaron de // 2 porque los tipos en el operador condicional son diferentes. Por tanto, el tipo de throw
expresión no parece ser nulo.
¿Así que qué es lo?
Si responde, respalde sus afirmaciones con citas de la Norma.
Esto resultó no ser tanto sobre el tipo de expresión de lanzamiento como sobre cómo el operador condicional maneja las expresiones de lanzamiento, algo que ciertamente no conocía antes de hoy. Gracias a todos los que respondieron, pero particularmente a David Thornley.
Respuestas:
De acuerdo con el estándar 5.16, párrafo 2, primer punto, "El segundo o tercer operando (pero no ambos) es una expresión de lanzamiento (15.1); el resultado es del tipo del otro y es un valor r". Por lo tanto, al operador condicional no le importa el tipo de expresión de lanzamiento, sino que solo usará el otro tipo.
De hecho, 15.1, párrafo 1 dice explícitamente "Una expresión de lanzamiento es de tipo void".
fuente
ISO14882 Sección 15
fuente
void
De [expr.cond.2] (operador condicional
?:
):Entonces, con
//1
usted estaba en el primer caso, con//2
, estaba violando "uno de los siguientes se mantendrá", ya que ninguno de ellos lo hace, en ese caso.fuente
Puede hacer que una impresora de tipos lo escupe :
Básicamente, la falta de implementación de
PrintType
hará que el informe de error de compilación diga:para que podamos verificar que las
throw
expresiones sean de tipovoid
(y sí, las citas estándar mencionadas en otras respuestas verifican que este no es un resultado específico de la implementación, aunque gcc tiene dificultades para imprimir información valiosa)fuente