Warum eine Ausnahme als Verweis auf const abfangen?

83

Ich habe oft gehört und gelesen, dass es besser ist, eine Ausnahme als Referenz auf const zu fangen, als als Referenz. Warum ist:

try {
    // stuff
} catch (const std::exception& e) {
    // stuff
}

besser als:

try {
    // stuff
} catch (std::exception& e) {
    // stuff
}
Kairol
quelle

Antworten:

66

Du brauchst:

  • eine Referenz, damit Sie polymorph auf die Ausnahme zugreifen können
  • Eine Konstante, um die Leistung zu steigern und dem Compiler mitzuteilen, dass Sie das Objekt nicht ändern werden

Letzteres ist nicht so wichtig wie Ersteres, aber der einzige wirkliche Grund, const zu löschen, besteht darin, zu signalisieren, dass Sie Änderungen an der Ausnahme vornehmen möchten (normalerweise nur dann nützlich, wenn Sie sie mit hinzugefügtem Kontext auf eine höhere Ebene übertragen möchten). .

Kornel Kisielewicz
quelle
1
"Sagen Sie dem Compiler, dass Sie das Objekt nicht ändern werden" - Ich nehme an, dass dies nützlich sein kann, wenn Sie das Objekt als Parameter an einen Funktionsaufruf übergeben.
Craig McQueen
1
Was meinst du mit "polymorph auf die Ausnahme zugreifen"?
Mango
3
@mango bedeutet vermutlich, eine virtuelle Funktion (wie std::exceptiondie what()Funktion von ') aufrufen zu können . Wenn Sie nach Wert abfangen, können Sie diese Funktion nicht aufrufen und die ursprünglichen Ausnahmedetails abrufen.
MM
11
Ich habe mir die Baugruppe angesehen, die von Apple Clang 7 und GCC 5 (mit Optimierung O3) hergestellt wurde, und sehe keinen Unterschied zwischen der Baugruppe const ref und der Baugruppe const ref. Also, ich denke, es gibt keinen Unterschied in der Optimierung für gcc und Apple Clang
Vasiliy Soshnikov
2
Der Compiler kann leicht erkennen, welche Objekte Sie ändern und welche nicht ( SSA und konstante Weitergabe). Eine bessere Erklärung ist erforderlich (oder ist es ein Mythos?).
Rustyx
31

Grundsätzlich gibt es überhaupt keinen Grund.

Ausnahmeobjekte befinden sich in ihrem eigenen Speicherbereich †, sodass Sie sich keine Gedanken über das Abfangen von Ausnahmen machen müssen, die in temporären Ausdrücken erstellt wurden.

Alles, was Sie tun, ist zu versprechen, dass Sie das Ausnahmeobjekt nicht ändern werden, aber da Ausnahmeobjekte eine unveränderliche Schnittstelle haben sollten , gibt es hier wirklich nichts Praktisches.

Es könnte jedoch dazu führen, dass Sie sich warm und gemütlich fühlen, wenn Sie es lesen - so ist es für mich!

Sie haben einen eigenen, speziellen, threadlokalen Stack.
Haftungsausschluss: Boost.Exception unterbricht dies, um funky Sachen zu machen und Ausnahmedetails nach der Konstruktion hinzuzufügen. Aber das ist Hackery!

Leichtigkeitsrennen im Orbit
quelle
Könnten Sie bitte näher darauf eingehen Exception objects live in their own memory space? Haben Sie eine gute Lektüre, um dies vorzuschlagen?
Richard Dally
@LeFlou: Ich könnte Sie auf den Standard verweisen, aber es wäre ein bisschen irreführend zu glauben, dass "eine gute Lektüre" ...: P
Leichtigkeitsrennen im Orbit
Auf jeden Fall ja, es wäre interessant, aus Standardsicht mehr darüber zu erfahren. Ich lese den technischen Bericht zur C ++ - Leistung . Haben Sie ein relevanteres Dokument?
Richard Dally
@LeFlou: Nun, es wird nicht maßgeblicher als der Standard selbst ...
Leichtigkeitsrennen im Orbit
1
@RichardDally prüfe C ++ Primer 5th , § 18.1.1 Excpetion Object. Er sagt , die Ausnahme - Objekt befindet im Raum, durch den Compiler verwaltet, die zugänglich sein garantiert ist , was Fang aufgerufen wird. Das Ausnahmeobjekt wird zerstört, nachdem die Ausnahme vollständig behandelt wurde.
Rick
5

Es teilt dem Compiler mit, dass Sie keine Funktion aufrufen, die die Ausnahme ändert, was zur Optimierung des Codes beitragen kann. Wahrscheinlich macht es keinen großen Unterschied, aber die Kosten dafür sind auch sehr gering.

Warpin
quelle
2

Wirst du die Ausnahme ändern? wenn nicht, kann es auch const sein. Der gleiche Grund, warum Sie const irgendwo anders verwenden sollten (ich sage SOLLTE, weil es auf der Oberfläche nicht wirklich so viel Unterschied macht, Compilern helfen könnte und auch Codierern hilft, Ihren Code richtig zu verwenden und keine Dinge zu tun, die sie nicht tun sollten).

Ausnahmebehandlungsroutinen können plattformspezifisch sein und Ausnahmen an lustigen Orten platzieren, weil sie nicht erwarten, dass sie sich ändern?

matt
quelle
-1

Aus dem gleichen Grund verwenden Sie eine const.


quelle
Und aus dem gleichen Grund, warum Referenzen Referenzen vorgezogen werden :-)
Dimitri C.
12
Einfach und unkompliziert, aber keine wirkliche Antwort.
Omnifarious