Was ist schneller: Fehlercode oder Exception?
-
Shade Of Mine schrieb:
Nein, da gibt es nichts zu diskutieren: wenn ich sage frage
"hat die map den key X"
dann ist die antwort ja oder nein.Korrekt, aber darauf bezog sich das Beispiel nicht. Es ging explizit darum, ob bei der Verwendung einer Map
class A { std::map<std::string, ValueType> map_; public: ValueType foo (std::string cont& key) { ... if (map_.end() == map_.find(key)) { // soll man hier werfen oder nicht } ... } };eine Exception werfen soll oder nicht. Das hängt davon ab, welche Anforderungen an A gestellt werden.
Shade Of Mine schrieb:
Eine exception darf maximal fliegen wenn die map nicht well-formed ist, zB unbalanziert ist oder sonstige invarianten nicht mehr stimmen.
Das ist ein vollständig anderes Problem, und zwar das Problem ob und wann die Member Function map::find eine Exception werfen darf.
-
Verwende Exceptions, die if-Abfragen von Error-Codes verhunzen dir nur den Cache wegen falscher Branch-Predictions deiner CPU.
-
~john schrieb:
Korrekt, aber darauf bezog sich das Beispiel nicht. Es ging explizit darum, ob bei der Verwendung einer Map
class A { std::map<std::string, ValueType> map_; public: ValueType foo (std::string cont& key) { ... if (map_.end() == map_.find(key)) { // soll man hier werfen oder nicht } ... } };eine Exception werfen soll oder nicht. Das hängt davon ab, welche Anforderungen an A gestellt werden.
Dann quote das richtige...
ohne zu wissen was foo ist, kann man nicht sagen was passieren soll, aber die funktion sieht von der signatur her sehr stark nach "eine exception muss fliegen" aus.
-
~john schrieb:
Shade Of Mine schrieb:
Eine exception darf maximal fliegen wenn die map nicht well-formed ist, zB unbalanziert ist oder sonstige invarianten nicht mehr stimmen.
Das ist ein vollständig anderes Problem, und zwar das Problem ob und wann die Member Function map::find eine Exception werfen darf.
Das kann exakt das selbe Problem sein - nämlich dann wenn es zu jedem "gültigen" Argument von foo() einen Eintrag in der map geben muss - was dann eine Invariante von A wäre. Die gültigen Argumente müssten dann natürlich über eine precondition festgelegt sein.
-
Shade Of Mine schrieb:
BUlli schrieb:
Seit wann heißt Exception Fehler? Wenn mich mein Englisch nicht täusch, heißt Exception Ausnahme. Und man wirft dann eine Exception, wenn eine Ausnahmesituation eintritt. Elemenet in Map nicht gefunden, ist eine Ausnahmesituation.
Wenn ich map[key]=value mache und key ist nicht da, dann Ja.
Nein, nicht bei std::map
http://msdn.microsoft.com/en-us/library/fe72hft9(VS.80).aspxmap::operator[]
Inserts an element into a map with a specified key value.
Type& operator[](
const Key& _Key
);Parameters
_Key
The key value of the element that is to be inserted.
Return Value
A reference to the data value of the inserted element.
RemarksIf the argument key value is not found, then it is inserted along with the default value of the data type.
~john schrieb:
class A { std::map<std::string, ValueType> map_; public: ValueType foo (std::string cont& key) { ... if (map_.end() == map_.find(key)) { // soll man hier werfen oder nicht } ... } };eine Exception werfen soll oder nicht. Das hängt davon ab, welche Anforderungen an A gestellt werden.
Wenn ein Element in der Map sein müsste, aber nicht da sein kann, wenn ein logikfehler im programm ist, dann würde ich ein assert verwenden, weil das schon beim entwickeln auffallen muss.
-
pumuckl schrieb:
- Was ist schneller?
Sollte imho keine Rolle spielen, zumal Fehler nicht gehäuft auftreten sollten. Ein Programm sollte im Fehlerfall lieber Augenmerk auf Korrektheit und Sicherheit als auf Schnelligkeit legen.So interpretiert ist das in der Tat eine sinnlose Frage. Vielleicht ist ja die Geschwindigkeit im Nicht-Fehlerfall gemeint. Meinjanur ...
weil Exceptions eben objektorientierte Ansatz zur Fehlerbehandlung sind
Ist das so? Was ist es denn, das Exceptions zum objektorientierten Ansatz macht?
-
und schrieb:
Wenn ich map[key]=value mache und key ist nicht da, dann Ja.
ich habe nicht von std::map geredet. aber ja, da sieht man schoen einen designfehler von std::map. weil man nicht wollte dass container exception ausloesen. nun ja. dafuer muss man dauernd map.find() verwenden wenn man mit maps arbeitet...
-
Bashar schrieb:
weil Exceptions eben objektorientierte Ansatz zur Fehlerbehandlung sind
Ist das so? Was ist es denn, das Exceptions zum objektorientierten Ansatz macht?
RAII?! oder schon mal den return-value vom CTor auf nen Error-Code geprüft? ^^
Oder du gehst den weg überInit ()für jede Klasse, die sonst einen (nicht-trivialen) CTor hätte - aber das halte ich nicht für die beste (weil unübersichtlicher) Möglichkeit...error-codes beschränken aber auch allgemein... was ist, wenn 100de funktionen jedes ma ne andere aufrufen und jedes ma wieder gucken müssen, ob die letzte ok war... wie bekommt man am ende den fehler raus? ok - man macht 100defines... und iwann kommt noch ne fkt zwischendrin dazu - und man muss bei jeder fkt wieder was dazu schreiben, die was damit zu tun hat... Bei exceptions macht man dann gar nix weiter, als die exception einfach so lang weiterzuwerfen, bis sie Verarbeitet / ausgewertet / auf sie reagiert / ... werden kann...
Error-Codes sind IMHO nur sinnvoll, wenn man mit dll`s arbeitet, da IMHO keine exceptions über dll-grenzen hinweg geworfen werden können (kein standardisierte aufbau der variablen (siehe z.bsp. vector und damit auch string - der speicherplatz eines MSVC-std::strings wird binär ausgegeben sicherlich anders sein, als einer unter xyz-erstellter))
bb
-
unskilled schrieb:
RAII?! oder schon mal den return-value vom CTor auf nen Error-Code geprüft? ^^
Oder du gehst den weg überInit ()für jede Klasse, die sonst einen (nicht-trivialen) CTor hätte - aber das halte ich nicht für die beste (weil unübersichtlicher) Möglichkeit...RAII kann ich auch ohne exceptions haben. RAII heisst ja nur, dass ich im DTor aufraeume. Aber ich kann auch den DTor durch ein return aufrufen.
Und statt exceptions koennte man bei einem CTor fehlschlag auch deferred error handling nehmen - wie es zB die fstreams machen wenn open() fehlschlaegt.
In anderen Sprachen kann man das Objekt dann zB auch NULL werden lassen.
error codes sind wahnsinnig umstaendlich, ja. aber exceptions haben nichts objekt orientiertes an sich. ausser dass man exceptions polymoprh verwenden kann - selbes gilt aber auch fuer error codes die returned werden.
also exceptions als OO ansatz zu sehen... ne, ich weiss echt nicht. ich sehe da nichts objekt orientiertes. zumindest nichts dass ich bei error codes nicht auch haben koennte.
aber dass macht exceptions nicht schlecht. denn oop == gut, alles andere == schlecht - stimmt ja nicht.
-
unskilled schrieb:
RAII?! oder schon mal den return-value vom CTor auf nen Error-Code geprüft? ^^
Ich seh nicht, was das mit OO zu tun hat. RAII ist eine C++-Spezialität. Ein Konstruktor könnte auch einfach null zurückgeben, wenn die Sprache das zulässt (ist in Objective-C so, IIRC).