Podniosłem to podczas jednej z moich krótkich wypraw na reddit:
http://www.smallshire.org.uk/sufficientlysmall/2009/07/31/in-c-throw-is-an-expression/
Zasadniczo autor zwraca uwagę, że w C ++:
throw "error"
jest wyrażeniem. W rzeczywistości jest to dość jasno opisane w standardzie C ++, zarówno w tekście głównym, jak i gramatyce. Jednak nie jest jasne (przynajmniej dla mnie), jaki jest typ wyrażenia? Zgadłem „ void
”, ale trochę poeksperymentowałem z g ++ 4.4.0 i Comeau dostarczyło ten kod:
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
}
Kompilatory nie miały problemu z // 1, ale barfed na // 2, ponieważ typy w operatorze warunkowym są różne. Tak więc rodzaj throw
wyrażenia nie wydaje się być nieważny.
Więc co to jest?
Jeśli odpowiesz, poprzyj swoje wypowiedzi cytatami ze Standardu.
Okazało się, że nie tyle chodziło o typ wyrażenia rzucającego, ile o to, jak operator warunkowy radzi sobie z wyrażeniami rzucania - coś, o czym z pewnością nie wiedziałem wcześniej. Dziękuję wszystkim, którzy odpowiedzieli, ale szczególnie Davidowi Thornleyowi.
Odpowiedzi:
Zgodnie ze standardem, punkt 5.16, paragraf 2, pierwszy punkt, „Drugi lub trzeci operand (ale nie oba) jest wyrażeniem rzutowym (15.1); wynik jest typu drugiego i jest wartością r”. W związku z tym operator warunkowy nie dba o typ wyrażenia rzucającego, ale po prostu użyje innego typu.
W rzeczywistości, punkt 15.1, akapit 1 mówi wyraźnie: „Wyrażenie rzucające jest typu void”.
źródło
ISO14882 sekcja 15
źródło
void
Z [wyraż.cond.2] (operator warunkowy
?:
):Tak więc, z
//1
tobą byłeś w pierwszym przypadku z//2
, naruszałeś zasadę „jedno z poniższych będzie utrzymywać”, ponieważ żaden z nich tego nie robi w tym przypadku.źródło
Możesz poprosić drukarkę typu wypluć to dla ciebie :
Zasadniczo brak implementacji dla
PrintType
spowoduje, że raport o błędzie kompilacji będzie zawierał:więc możemy faktycznie zweryfikować, czy
throw
wyrażenia są typuvoid
(i tak, standardowe cytaty wspomniane w innych odpowiedziach potwierdzają, że nie jest to wynik specyficzny dla implementacji - chociaż gcc ma trudności z wydrukowaniem cennych informacji)źródło