Ich habe dies in einem meiner kurzen Streifzüge zum Reddit aufgegriffen:
http://www.smallshire.org.uk/sufficientlysmall/2009/07/31/in-c-throw-is-an-expression/
Grundsätzlich weist der Autor darauf hin, dass in C ++:
throw "error"
ist ein Ausdruck. Dies ist im C ++ - Standard sowohl im Haupttext als auch in der Grammatik ziemlich klar formuliert. Was jedoch (zumindest für mich) nicht klar ist, ist die Art des Ausdrucks? Ich vermutete " void
", aber ein bisschen Experimentieren mit g ++ 4.4.0 und Comeau ergab diesen Code:
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
}
Die Compiler hatten kein Problem mit // 1, aber mit // 2 gesperrt, da die Typen im bedingten Operator unterschiedlich sind. Die Art eines throw
Ausdrucks scheint also nicht ungültig zu sein.
Also, was ist es?
Wenn Sie antworten, stützen Sie Ihre Aussagen bitte mit Zitaten aus dem Standard.
Es stellte sich heraus, dass es nicht so sehr um die Art eines Wurfausdrucks ging, sondern vielmehr darum, wie der bedingte Operator mit Wurfausdrücken umgeht - etwas, von dem ich bis heute sicherlich nichts wusste. Vielen Dank an alle, die geantwortet haben, besonders aber an David Thornley.
Antworten:
Gemäß dem Standard, 5.16 Absatz 2, erster Punkt: "Der zweite oder dritte Operand (aber nicht beide) ist ein Wurfausdruck (15.1); das Ergebnis ist vom Typ des anderen und ist ein Wert." Daher ist es dem bedingten Operator egal, welcher Typ ein Wurfausdruck ist, sondern er verwendet nur den anderen Typ.
Tatsächlich heißt es in Absatz 1, 15.1, ausdrücklich: "Ein Wurfausdruck ist vom Typ void."
quelle
ISO14882 Abschnitt 15
quelle
void
Aus [Ausdruck.2] (bedingter Operator
?:
):Wenn
//1
Sie also im ersten Fall mit waren//2
, haben Sie gegen "eine der folgenden Bedingungen" verstoßen, da in diesem Fall keiner von ihnen dies tut.quelle
Sie können einen Typdrucker haben ausspucken lassen :
Grundsätzlich führt die fehlende Implementierung für
PrintType
dazu, dass im Kompilierungsfehlerbericht Folgendes angegeben wird:So können wir tatsächlich überprüfen, ob
throw
Ausdrücke vom Typ sindvoid
(und ja, die in anderen Antworten erwähnten Standardzitate bestätigen, dass dies kein implementierungsspezifisches Ergebnis ist - obwohl es für gcc schwierig ist, wertvolle Informationen zu drucken).quelle