Ist die starke Sicherheitsgarantie für Ausnahmen mit einem Wertübergabeargument möglich, das zur Zerstörung führen kann?

8

Angenommen, Sie haben einen Typ mit einem Wurfzerstörer und eine Funktion, die ihn nach Wert empfängt.
Kann diese Operation jemals etwas Besseres als die grundlegende Ausnahmegarantie bieten?
Oder anders formuliert: Kann man die Zerstörung des als Wert übergebenen Arguments außer Acht lassen, wenn festgestellt wird, ob eine Operation eine Commmit-and-Rollback-Semantik aufweist?

#include <cstdlib>

struct X {
    ~X() noexcept(0) {
        if(rand()%6 == 0) throw 0;
    }
    // some state
};

void update(database db, X arg) noexcept;

X x;
update(db, x);

Persönlich basierend auf der Definition aus Wikipedia

  1. Starke Ausnahmesicherheit , auch als Commit- oder Rollback-Semantik bezeichnet : Vorgänge können fehlschlagen, fehlgeschlagene Vorgänge haben jedoch garantiert keine Nebenwirkungen, sodass alle Daten ihre ursprünglichen Werte beibehalten

Ich denke nicht, dass es nützlich ist, dies updateals stark ausnahmesicher zu beschreiben , obwohl die Funktion selbst nicht einmal werfen kann.

Ich würde mich freuen, wenn mir jemand die Torheit meines gegenwärtigen Verständnisses zeigt oder ein besseres Argument liefert.

Deduplikator
quelle
Was passiert, wenn eine Methode in der Klasse ausgelöst wird und der Aufrufer beschließt, das Objekt zu entsorgen? Wird der Destruktor die Transaktion noch abschließen?
Robert Harvey
Methode in welcher Klasse? Und welche Transaktion abschließen? Entschuldigung, aber ich bin jetzt verwirrt.
Deduplikator
Nun, es sei denn, es wird ein Erinnerungsmuster verwendet oder es handelt sich um eine Datenbanktransaktion. Ich sehe nicht, wie der Status der Klasse nicht verloren geht, wenn das Objekt entsorgt wird, es sei denn, Sie sagen, es ist eine zustandslose Klasse.
Robert Harvey
2
Die Frage wurde durch das Argument inspiriert hier: chat.stackexchange.com/rooms/32049/... chat.stackexchange.com/rooms/32061/...
Deduplicator
4
Im Allgemeinen ist ein Wurfzerstörer ein absolutes Gift für alle Ausnahmesicherheitsgarantien. Es wird nur um Größenordnungen schwieriger.
Sebastian Redl

Antworten:

7

Ich bin mir im Nachhinein nicht sicher, aber wenn updatees generisch oder Xabstrakt war (zB geklont und zerstört) - dh wenn updateich nichts Konkretes wissen konnte X, dann würde ich es für alle praktischen Zwecke als stark beschreiben Ausnahmesicherheitsgarantie. Zumindest entspricht dies einer starken Ausnahmesicherheitsgarantie, die Sie jemals in einem abstrakten Kontext erhalten werden, ohne einen Datentyp zu röntgen.

Ist Xjedoch konkret, so dass diese Frage viel unschärfer wird. Ich bin immer noch versucht zu sagen, dass update"eine starke Ausnahmesicherheitsgarantie besteht", da es alles tut, was es tun kann, um dies durchzusetzen. Klingt das nach verrücktem Gerede? Das tut es mir, aber ich kann es nicht viel besser ausdrücken.

Insbesondere im Kontext einer Teamumgebung, in der ein Autor implementiert updateund der andere implementiert X, könnte nichts jemals eine starke Ausnahmesicherheitsgarantie bieten, da Xdiese in einer Weise geändert werden könnte, die die Garantie in einer Weise bricht, die völlig außerhalb der Kontrolle von liegt update. Aus praktischen Gründen denke ich, wenn updatees alles tut, was es kann und sollte, um seine eigenen Nebenwirkungen auf außergewöhnlichen Wegen zurückzudrängen, bietet es praktisch eine starke Ausnahmesicherheitsgarantie.

Andernfalls wird die starke Sicherheitsgarantie für Ausnahmen in so vielen Szenarien unpraktisch. Dinge können sich außerhalb der Kontrolle der Funktion ändern. Dinge könnten auf eine Weise abstrakt sein, die über das Wissen der Funktion hinausgeht. Es wäre fast unmöglich, die gesamte Garantie irgendwo zu geben. In diesem Fall könnten wir sagen, dass die starke Ausnahmegarantie der updatePropagierung eine Verpflichtung zur XEinhaltung propagiert , oder ist es updateerforderlich zu wissen, wie Xsie jederzeit umgesetzt wird? Ich weiß es nicht. Das ist alles so oder so sehr unpraktisch und ich mag keine Unpraktikabilität.

Also werde ich mit dem Rohöl gehen, ja, " updateist Xausnahmesicher , aber fubar und hat alles durcheinander gebracht. Es ist update'szumindest kein Fehler. Verklage nicht den Autor des Updates! Verklage den Autor von X!" . Ich möchte hier beschreiben X, dass es einfach nur fubar ist und updatemöglicherweise eine starke Ausnahmesicherheitsgarantie bietet, die durch die Tatsache, dass Xes fubar ist, verschraubt wird. Das heißt, es sei denn, es gibt ein sehr schwieriges Verständnis auf Schnittstellenebene, das der X'sDestruktor auslösen soll. In diesem Fall habe ich keine Ahnung, wie ich es beschreiben soll, außer als "großes Problem". Ich denke, wir brauchen Kleingedrucktes und Haftungsausschlüsse, um diese Garantien zu erhalten.Update bietet eine starke Ausnahmesicherheitsgarantie, sofern [...]. Keine Rückerstattung, wenn dies nicht der Fall ist!

Dies ist für mich wie eine philosophische Frage, interessant zu denken, aber vielleicht eine ohne perfekte Antwort. Und was sind Garantien überhaupt? Können wir etwas garantieren? Ich könnte garantieren, dass das Trinken von Bier mich betrinken würde und das könnte die ganze Zeit wahr sein, aber was ist, wenn ein Außerirdischer eingreift und eine Art außerirdische Technologie verwendet, die mich nüchtern macht, egal wie viel ich trinke? Ich kann nicht garantierendass dies nicht passieren wird. Ich kann nur sagen, dass dies höchst unwahrscheinlich ist und dass ich dagegen machtlos wäre, wenn ein solches Ereignis eintreten würde. Ich habe meinen Teil getan. Ich habe mein Bier getrunken. Ich soll mich betrinken. Ich garantiere es nachdrücklich. Aber es ist nicht sicher. Es besteht immer eine gewisse Wahrscheinlichkeit, auch wenn diese astronomisch weit entfernt ist, dass die Garantie möglicherweise nicht zutrifft. Wie wäre es mit Thread-Sicherheit? Was ist, wenn das außerirdische Raumschiff kommt und unsere Hardware zappt und Anweisungen im Speicher neu anordnet, sodass eine formell threadsichere Funktion zur Laufzeit nicht mehr threadsicher ist? Ich kann nicht garantieren, dass dies nicht passieren wird. Aber ich werde die Sicherheit der Fäden garantieren, unabhängig davon, ohne auf so ein Kleingedrucktes über außerirdische Raumschiffe einzugehen, denn dadurch fühlen sich die Leute nett und beruhigt, und ich sage, dass ich '

Descartes sagte einmal: "Ich denke also, ich bin es." Woher weiß er das? Was ist, wenn er nicht ist? Er könnte ein "bin nicht" sein, aber vielleicht können "nicht" "denken". Ich weiß nicht einmal, ob ich existiere. Was bedeutet Denken überhaupt? Es ist wie ein Wort, mit dem Menschen einen Prozess beschreiben, der scheinbar introspektiv abläuft und so aussieht, als würden wir, die wir vielleicht gar nicht existieren, Entscheidungen treffen.

Was ist, wenn wir alle nur Bits und Bytes auf einer Maschine sind? Wie diese Blondine oder Brünette in der Matrix. Wie kann übrigens eine Blondine oder besonders eine Brünette in einem so kleinen Strom von Charakteren gespeichert werden? Sind sie wie UTF2048? Es war eine Art fremder Strom von Charakteren, aber es schien nicht zu viele einzigartige Charaktere zu geben. Vielleicht ist es eine Art Funktionsaufruf. Ich bin mir jedenfalls nicht sicher, ob wir etwas garantieren können. Es ist alles relativ zu dem, was wir für wahr halten.


quelle
5
"Also sollten" Ausnahmesicherheit "jeglicher Art und" Wurfzerstörer "wahrscheinlich niemals in einem Satz kombiniert werden. Sie schließen sich praktisch aus." +1, kann mit dieser Logik nicht streiten. Wenn Sie denken, dass Sie können, sind Sie nicht logisch.
Ich sehe nicht, wie dies die ursprüngliche Frage beantwortet. Das Problem hierbei ist, dass arg genau beim Beenden der Funktion zerstört wird. Die Funktion hat keine Chance, dies zu erfassen. Wenn die Funktion etwas getan hat, hat sie keine Chance, es zurückzusetzen.
Nir Friedman
2
Ja, das ist die richtige Schlussfolgerung, es wird nicht weniger richtig, wenn man unangenehm ist. Im Fall von Vektoren ist es illegal, dass der Destruktor des enthaltenen Typs jemals ausgelöst wird : stackoverflow.com/questions/26902006/… . Ich verstehe Ihren "teamorientierten" Ansatz, aber ehrlich gesagt betrachtet er ihn eher aus einer Perspektive der Fairness als der Korrektheit.
Nir Friedman
2
Meine bevorzugte Interpretation ist einfach, dass das Einwerfen eines Destruktors ein undefiniertes Verhalten ist, und welche Ausnahme eine Funktion garantiert, basiert alle auf der impliziten Annahme, dass kein undefiniertes Verhalten auftritt (tatsächlich macht alles in der Sprache diese Annahme). Wenn undefiniertes Verhalten das Formatieren Ihrer Festplatte beinhalten kann, kann dies sicherlich das Verletzen der ansonsten korrekten Ausnahmegarantien für alles andere im Programm beinhalten.
Ixrec
1
@Ixrec Das mag Ihre bevorzugte Interpretation sein, aber das Werfen von einem Destruktor ist im Allgemeinen nicht ub, das ist einfach eine Tatsache.
Nir Friedman
-1

Technisch gesehen kann es möglicherweise die starke Ausnahmegarantie bieten. Bezeichnenderweise kann es die starke Ausnahmegarantie nur in dem trivialen Fall bieten, in dem es nichts tut.

Herb Sutter spricht von einem ähnlichen (und intuitiveren) Fall, in dem eine Funktion ein Argument nach Wert annimmt, das einen Konstruktor für auslösende Kopien enthält. Sie können eine solche Funktion mit Ausnahme von kennzeichnen. Technisch gesehen tritt die Ausnahme im "Kleber" zwischen dem aufrufenden Code und der aufgerufenen Funktion auf, nicht innerhalb der Funktion selbst. Das ist auch hier der Fall. Da die Ausnahme technisch nicht in update ausgelöst wird, können Sie (möglicherweise) argumentieren, dass das Update selbst den Fehler nicht generiert und daher die starke Ausnahmegarantie bieten kann.

Wenn das Update etwas bewirkt, kann das Aufrufen (und nichts anderes) dazu führen, dass sich der Zustand der Welt ändert und eine Ausnahme ausgelöst wird, wodurch die Garantie für starke Ausnahmen verletzt wird.

Nir Friedman
quelle
Kommentare sind nicht für eine ausführliche Diskussion gedacht. Dieses Gespräch wurde in den Chat verschoben .
maple_shaft