2016-03-23 5 views
6

diese kurze Schnipsel vor:eine Ausnahme von Wert Catching - gcc und klappern nicht einverstanden

struct B { 
    B() = default; 
    explicit B(B const&) { } 
}; 

struct D : B { }; 

int main() { 
    try { 
     throw D{}; 
    } 
    catch(B) { 
    } 
} 

gcc akzeptiert diesen Code, Klirren hält es schlecht gebildet mit:

main.cpp:17:13: error: no matching constructor for initialization of 'B' 
    catch(B) { 
      ^

Wer hat Recht?

+0

Auch, vielleicht haben beide Recht .. – xaxxon

+0

@xaxxon Ich bezweifle, dass etwas wie das ist nicht näher bezeichnet. Entweder soll es gültig sein oder es sollte ungültig sein. Wie auch immer, Ausnahmen sind seltsam. – Barry

+0

Hmm, GCC lehnt es korrekt ab, wenn Sie versuchen, ein 'B' zu werfen, aber nicht, wenn Sie versuchen, ein' D' zu werfen. –

Antwort

4

I denke, Dies ist ein GCC-Bug (und da niemand diese Antwort noch downvoted, habe ich es als 70375 eingereicht).

Beide Compiler stimmen richtig, dass D{} gefangen werden sollte, da pro [except.handle]/3, die nur überprüft, ob B eine Basisklasse von D ist.

Aber die Initialisierung des Handlers in [except.handle]/15 definiert ist als:

Die Variable von der Ausnahme Deklaration, vom Typ cvT oder cvT&, aus dem Ausnahmeobjekt initialisiert wird, vom Typ E, wie folgt:
- Wenn T eine Basisklasse von E ist, wird die Variable kopierinitialisiert (8.5) vom entsprechenden Basisklassenunterobjekt des Ausnahmeobjekts;

, dass diese Initialisierung bedeutet, arbeitet als:

D __temporary_object{}; 
B __handler = static_cast<B&>(__temporary_object); 

die seit B ‚s nicht zugelassen werden sollte, Copy-Konstruktor explicit markiert (und Copy-Initialisierung schneidet es einfach nicht).

+0

und entfernen Sie die "explizite" in Ihrem Beispiel macht Clong akzeptieren die Ausnahme. – xaxxon

Verwandte Themen