2010-09-17 4 views
7

Ich versuche, die atomare Bibliothek aus dem C++ 0x-Entwurf zu implementieren. Insbesondere bin ich der Umsetzung §29.6/8, die store Methode:Implementieren von Atom <T> :: Geschäft

template <typename T> 
void atomic<T>::store(T pDesired, memory_order pOrder = memory_order_seq_cst); 

Die Anforderung lautet:

Die Reihenfolge Argument gilt nicht memory_order_consume, memory_order_acquire, noch memory_order_acq_rel werden.

Ich bin nicht sicher, was zu tun ist, wenn es einer von diesen ist. Sollte ich nichts tun, eine Ausnahme auslösen, ein undefiniertes Verhalten bekommen oder etwas anderes tun?

P. S .: "C++ 0X" sieht irgendwie wie ein toter Fisch: 3

+7

+1 für einen toten Fisch. – GManNickG

Antwort

9

Tun Sie, was Sie wollen. Es ist egal.

Wenn ISO besagt, dass Sie "nichts tun" sollen, ist dies ein undefiniertes Verhalten. Wenn ein Benutzer das tut, hat er den Vertrag mit der Implementierung verletzt, und die Implementierung ist in seinem Recht zu tun, wie es ihm gefällt.

Was Sie entscheiden, liegt ganz bei Ihnen. Ich würde mich für alles entscheiden, was Ihre Umsetzung "besser" macht (in Ihren Augen, seien Sie schneller, lesbarer, unterliegen dem Prinzip des geringsten Erstaunens und so weiter).

Ich, ich würde für die Lesbarkeit gehen (da ich das Ding behalten müsste) mit der Geschwindigkeit, die eine nahe Sekunde nimmt.

0

Ich würde lieber vage vernünftiges Verhalten, dass etwas verrückt.

Nun, als potenzieller Verbraucher Ihrer Bibliothek, hier ist, was ich möchte: Wenn es keinen Leistungsaufwand für die dokumentierte Verwendung gibt, dann sehen Sie, ob einer der memory_order-Werte eine funktionale Obermenge der anderen bietet, insbesondere etwas entsprechendes zu dem, was ein Anrufer naiv erwarten könnte, dass die nicht unterstützten Modi tun (wenn irgendeine vernünftige Erwartung gebildet werden kann). Der Anrufer kann den langsamsten, sichersten Modus erhalten, aber das ist besser als etwas funktionell falsches. Sie minimieren die Abhängigkeit des Client-Codes davon, dass alles perfekt für Ihren Code ist. Das Problem dabei - im Vergleich zu einer Assert/Exception - ist, dass es in einer Testumgebung unbemerkt bleibt. Überlegen Sie also auch std :: cerr eine Erklärung, indem Sie eine statische Variable verwenden, um die Meldungen auf eine pro Prozesslauf zu beschränken. Das ist eine sehr nützliche Diagnose.

Eine Ausnahme, fatale Behauptung etc. könnte eine Client-Anwendung zu einem sehr unbequemen Moment herunterfahren .... Scheint ein bisschen drakonisch, und nicht etwas, was ich besonders schätzen würde. Eine andere Möglichkeit ist, dass eine Umgebungsvariable dieses Verhalten steuert.

(Es gibt vermutlich ein ähnliches Problem für Werte, die nicht einmal in der aktuellen Aufzählung sind.)

+3

Wenn Sie sich auf undefiniertes Verhalten verlassen, würde ich lieber meine Implementierung formatieren Ihre Festplatte (was eigentlich gültiges Verhalten ist). Das liegt daran, dass Sie während der Wiederherstellung keinen Buggy-Code ausgeben werden :-) Es kann kein funktionell falsches Verhalten sein, wenn es undefiniert ist, was "undefiniert" bedeutet. – paxdiablo

+0

@paxdiablo. Was für eine sinnlose Aussage. Undefiniertes Verhalten wird normalerweise versehentlich aufgerufen, daher die Frage an erster Stelle. Erwachsen werden. Es heißt "defensive Programmierung", und ich habe genug von allen Design-by-Contract-Typen, die sich wie schlechte Jungs verhalten. –

+3

Was Sie lieber bekommen würden, ist irrelevant. Der Standard gibt an, dass Sie das nicht tun dürfen, damit der Implementierer frei tun kann, was er will. Sie können entscheiden, es elegant zu behandeln, oder sie können es (und das ist meine Präferenz) einfach ignorieren und Sie können Ihren eigenen Code reparieren. Ich bin nicht da, um Sie zu halten, wenn Sie die Regeln brechen. Es ist nicht anders als Leute, die über die Tatsache jammern, dass "i = ++ i + i ++;" nicht wie erwartet funktioniert - die Antwort lautet: "Tu es nicht!" Und, wenn du es warst, hat das meine Antwort gegeben (Annahme von meiner Seite, aber wahrscheinlich richtig in Anbetracht Ihres Tones), ich denke, ich bin "erwachsen" genug, um nicht zu rächen. – paxdiablo

0

Ich ziehe eine Kompilierung Fehler. Wenn nicht, dann ein assert() Fehler.

Assert ist gut, da es sich aus der Release-Version zusammensetzt und die Leistung nicht beeinträchtigt.

Fehler bei der Kompilierungszeit sind noch besser, da sie eine schnellere Rückmeldung ermöglichen, ohne dass die Software über den Fehler stolpern muss. Kompilierzeitfehlerprüfungen sind eine Sache, die ich an C++ - Code gegenüber Python, Ruby, Perl-Code liebe.

Verwandte Themen