2013-04-26 5 views
7

Vor kurzem in meinem Code habe ich explizit schreiben noexcept(false) auf Funktionen, die ich weiß Ausnahmen zu werfen, vor allem für Menschen, die den Code lesen. Ich frage mich jedoch, ob dies Auswirkungen auf das Verhalten meines Codes oder auf die Art hat, wie der Compiler ihn interpretiert. Macht es einen Unterschied?Hat das Hinzufügen von `noexcept (false)` einen Vorteil für den Code?

Hinweis: Ich bin mir bewusst, dass Destruktoren implizit noexcept sind und dass Sie noexcept(false) angeben müssen, um das zu ändern, ich frage mich über andere Funktionen.

Antwort

10

Da sie keine Ausnahme-Spezifizierer und explizit Angabe noexcept(false) äquivalent sind, siehe §15.4/12:

Eine Funktion ohne exception-Spezifikation oder mit einer Ausnahme-Spezifikation der Form noexcept(constant-expression) wobei die Konstante Ausdruck Erträge false ermöglicht alle Ausnahmen.

Also der Compiler sollte nicht zwischen ihnen unterscheiden, wenn Ausnahmen berücksichtigt werden.


Noch wichtiger ist, gibt es keine Notwendigkeit für Sie auf noexcept(false) auf Ihre Funktionen Anheften werden. Als C++ - Entwickler sollten Sie davon ausgehen, dass jede Funktion standardmäßig ausgelöst wird (weshalb der Standard diese Haltung einnimmt), also fügen Sie keine neuen Informationen hinzu, indem Sie sie ausschreiben. es ist Zeitverschwendung für alle.

Vielmehr machen den speziellen Fall markieren, wo eine Funktion definitiv nicht mit noexcept werfen, und sie die Fälle markieren, wo eine Funktion kann Wurf mit noexcept(condition) auf einer Bedingung abhängig.

Wenn Ihre Funktion absichtlich die Quelle einer Ausnahme E ist, schreiben Sie das in Ihrer Dokumentation.

+1

Beachten Sie, dass Destruktoren in C++ 11 standardmäßig 'noexcept (true)' sind. Wenn Sie das überschreiben möchten, müssen Sie 'noexcept (false)' hinzufügen. Das ist jedoch fast immer eine schlechte Idee. (Ich wage zu sagen, dass es immer eine schlechte Idee ist; ich helfe nur mit "fast", falls ich nicht phantasievoll genug bin.) Riesige Code-Schwaden, einschließlich der Standardbibliothek, setzen voraus, dass Destruktoren immer erfolgreich sind und es sehr ist Es ist schwierig, den Code fehlerfrei zu verfassen, wenn die Bereinigung fehlschlagen kann. In vielen Situationen ist dies unmöglich (z. B. statische Initialisierung oder mehrere Klassenmitglieder). –

+1

Sie könnten '/ * noexcept (false) * /' verwenden, um zu signalisieren, dass Sie nicht versehentlich vergessen haben, 'noexcept' an die Schnittstelle – TemplateRex

+1

hinzuzufügen. Ich wünschte, es gäbe eine Möglichkeit, eine Funktion so zu markieren, dass sie sogar Compiler wirft kann durch interprocedural Analyse feststellen, dass es unmöglich werfen könnte. – kchoi

-1

In seinem Buch More Exceptional C++, Herb Sutter hat folgende Schnipsel (S. 130).:

Die richtige Antwort auf das Beispiel 19-1 ist viel einfacher:

// Example 19-4: The right solution 
// 
T::~T() /* throw() */ 
{ 
// ... code that won't throw ... 
} 

Beispiel 19-4 zeigt, wie man eine Designentscheidung trifft anstatt zu waffeln.

Beachten Sie, dass die throw() throws-nothing Ausnahmespezifikation nur ein Kommentar ist. Das ist die Art, die ich gewählt habe, um zu folgen, in Teil , weil es sich herausstellt, dass Ausnahmespezifikationen viel weniger Vorteil geben, als sie wert sind. Ob Sie sich entscheiden, die Spezifikation tatsächlich zu schreiben, ist Geschmackssache.

(Hervorhebung von mir)

Also, ich glaube, ich muss darauf hinweisen, dass einer der führenden Experten in C++ exception-sicheren Code gegen das gesamte Konzept für den Compiler Ausnahme Spezifikationen des Hinzufügens zu sein scheint, zu verwenden (aber immer noch im Code für die Programmierer zu verstehen).

Nur dachte, es könnte interessant sein info ...

+4

'throw()' und 'noexcept (true)' unterscheiden sich genau aus diesem Grund. Ich betrachte es als _vital_ für Move-Konstruktoren und verschiebe Zuweisungen als "noexcept (true)" und würde alles andere als einen Fehler betrachten. –

+0

@MooingDuck: Nach dem Lesen dieser: http://herbsutter.com/2010/08/28/trip-report-august-2010-iso-c-standards-meeting/ Ich fühle, dass sein Punkt immer noch bleibt. Ist es so? – Escualo

+0

[Hier] (http://herbsutter.com/2010/03/13/trip-report-march-2010-iso-c-standards-meeting/) und [Hier] (http://www.gotw.ca /publications/mill22.htm) er erwähnt, dass 'throw()' schlecht ist, weil es seltsame Dinge tut. In dem von Ihnen geposteten Link scheint er keine Bedenken zu haben, 'nothrow (true)' auf die gesamte Standardbibliothek anzuwenden. –

Verwandte Themen