C++ frequently questioned answers
-
-
Toll wäre so eine Seite wenn sie von kompetenten Leute aufgezogen werden würde. Aber so sind es immer eine handvoll valider Punkte und dann massig bullshit
PS:
Ich kann nur immer wieder Imperfect C++ empfehlen. Das ist eine deutlich bessere Lektüre also so ein quark wie c++ fqa lite. wobei die leute natürlich deutlich mehr auf die fqa stehen - weil es halt cooler ist.
-
Shade Of Mine schrieb:
Toll wäre so eine Seite wenn sie von kompetenten Leute aufgezogen werden würde.
so inkompetent kann er gar nicht sein:
http://yosefk.com/about.html schrieb:
I'm a software developer at Mobileye, maker of real time computer vision systems for automotive safety. Preventing you from running over a pedestrian, that kind of thing. I work on our custom hardware and the supporting code - compilers, debuggers, drivers, schedulers and stuff.
ich wette, der macher dieser seite hat sich ziemlich über c++ aufgeregt. sonst kämer keine auf die idee, sich diese mühe zu machen.
-
Gemeint war Kompetent im Sinne von gleiche Meinung haben.
-
Kompetent im Sinne von gleiche Meinung
-
Jester schrieb:
Gemeint war Kompetent im Sinne von gleiche Meinung haben.
Nein, aber simples Beispiel:
Der Autor findet es komisch dass man Exception (ein mechanismus den er in C++ nicht mag) verwenden muss um CTor fehlschlaege anzuzeigen.
Ob Exception in C++ gut oder schlecht implementiert sind, ist persoenliche Meinung, aber ob ich Exceptions fuer CTor fehlschlaege verwenden muss oder nicht, ist ein leich zu pruefender Fakt.
Man sehe sich std::fstream an.
Beweisaufnahme abgeschlossen.und auf der Seite regnet es solche Sachen.
Wie ich aber gesagt habe: teilweise stimmen kritikpunkte natuerlich auch. zB viel zu lange compiletimes und unnoetig schwere protierung zwischen compilern, etc.Aber viele Sachen sind einfach schwachsinn. zB reitet der autor auch gerne darauf herum dass Destruktoren nicht fehlschlagen duerfen. Das komplette Destruktoren-Kapitel geht um nichts anderes. Lustig ist aber, dass ich keine Sprache kenne wo Destruktoren sinnvollerweise fehlschlagen koennen, bzw. wenn sie fehlschlagen wie man darauf reagieren kann.
Ich koennte relativ lange so weiter machen... Viele Punkte auf dieser Seite sind keine Meinungen sondern einfach falsch. Und an vielen Stellen wird kritisiert dass der Standard gefaehrliches Verhalten nicht verbietet sondern die Compiler in solchen Faellen warnen laesst. Wobei es hier halt wieder persoenliche Meinung ist ob das ein Fehler ist.
Aber es sind eine reihe an Aussagen einfach falsch - und das macht die Seite (wenn man von dem schreibstil mal absieht der sowieso kein bisschen objektiv ist) einfach nur unserioes.
Deshalb finde ich Publikationen wie zB Imperfect C++ hier deutlich besser, da dort keine Maerchen erzaehlt werden. Aber manche Menschen moegen ja Maerchen...
-
Warum soll man allgemein (also nicht nur in C++) für Ctor Fehlschläge nicht Exceptions verwenden? In jeder 3ten Zeile erst mal zu prüfen ob mein Object n Errorflag gesetzt hat ist doch nicht besser.
-
HouseOfTheRaisingSun schrieb:
Warum soll man allgemein (also nicht nur in C++) für Ctor Fehlschläge nicht Exceptions verwenden? In jeder 3ten Zeile erst mal zu prüfen ob mein Object n Errorflag gesetzt hat ist doch nicht besser.
Weil laut Autor Exception in C++ ein kaputter Mechanismus sind. Genauso wie Vererbung, virtuelle Methoden, Access Control, Destruktoren, Resourcen Management, Zeiger, Templates, Operatoren Ueberladung, inlining,... eigentlich so ziemlich alles.
Aber frag da lieber Jester, der erklaert dir das warum man Exceptions in C++ eigentlich nicht verwenden kann und deshalb Konstruktoren in C++ garnicht sinnvoll verwendbar sind und dadurch Objekte generell nicht (vorallem da ja Destruktoren auch nicht richtig funktionieren) und da spaete Bindung und Vererbung generell in C++ sowieso komplett kaputt ist, sollte man lieber gleich auf alles verzichten. Jester kennt sich da sicher aus. Frag ihn mal.
-
Erinnert mich ein wenig an diese Fun-Seite.
-
Shade Of Mine schrieb:
zB reitet der autor auch gerne darauf herum dass Destruktoren nicht fehlschlagen duerfen.
wieso nicht dürfen? schiefgehen kann immer was. z.b. funktionen die fehlschlagen oder sogar ein heap crash. in dem fall könnte man ja auch 'ne exception abschicken. natürlich keine, die mit 'new' erzeugt wurde, wenn der heap kaputt ist. aber wie ich die lage einschätze, ist das alles in c++ insider-kreisen strengstens verboten.
-
~fricky schrieb:
wieso nicht dürfen? schiefgehen kann immer was. z.b. funktionen die fehlschlagen oder sogar ein heap crash. in dem fall könnte man ja auch 'ne exception abschicken. natürlich keine, die mit 'new' erzeugt wurde, wenn der heap kaputt ist. aber wie ich die lage einschätze, ist das alles in c++ insider-kreisen strengstens verboten.
Welche Sprache kann da noch was vernünftiges machen? Es werden soviele logik Fehler in Programme eingebaut, dass ein Destruktor der aufgrund von total extoischen Problemen nicht funktionieren könnte doch vollkommen egal ist.
-
~fricky schrieb:
aber wie ich die lage einschätze, ist das alles in c++ insider-kreisen strengstens verboten.
Und in welcher Sprache nicht?
Nicht umsonst schreibt man in Java immerfinally { if(f!=null) { try { f.close(); } catch(Exception e) {} } }
Weil man nicht sinnvoll reagieren kann (in 99% der Faelle).
Fuer soetwas kritisches gibt es dann andere Moeglichkeiten - die natuerlich umstaendlicher sind, aber man braucht sie ja auch eigentlich nie (und wenn man sie mal braucht dann ist es natuerlich nervig wenn es umstaendlich ist, aber solange es machbar ist, ist es imho ok).
java finalizers duerfen uebrigens auch nicht fehlschlagen.
Sag mir mal eine Sprache wo es regelmaessig vorkommt dass cleanup funktionen fehlschlagen und man sinnvoll darauf reagiert. problem ist halt: wenn ich sage: trenne die Verbindung zum Server und es schlaegt fehl, was mache ich dann? Mich aergern und die Verbindung halt offen lassen uU vorher einen forced shutdown probieren (nur ist ein forced shutdown nicht immer moeglich, zB ein delete bietet mir keine moeglichkeit fuer einen forced shutdown) und danach bin ich ratlos.
Alles hat immer vor und nachteile.
-
~fricky schrieb:
Shade Of Mine schrieb:
zB reitet der autor auch gerne darauf herum dass Destruktoren nicht fehlschlagen duerfen.
wieso nicht dürfen? schiefgehen kann immer was. z.b. funktionen die fehlschlagen oder sogar ein heap crash. in dem fall könnte man ja auch 'ne exception abschicken. natürlich keine, die mit 'new' erzeugt wurde, wenn der heap kaputt ist. aber wie ich die lage einschätze, ist das alles in c++ insider-kreisen strengstens verboten.
Ich nehme Dich mal in die Insider-Kreise von C++ auf, indem ich Dir erkläre, warum ein Destruktor keine Exception werfen darf.
Das Problem ist, dass Destruktoren automatisch beim verlassen des Gültigkeitsbereiches von Stack-Variablen aufgerufen werden. Das lässt sich noch nicht mal verhindern. Der Gültigkeitsbereich kann aber auch durch eine andere Exception verlassen werden. Der Codefluß ist dann gerade zwischen einem throw und einem catch, also gerade beim auffangen einer Exception. Der Usercode wirft jetzt eine weitere Exception. Das kann nicht gut gehen. Was sollte das System denn dann machen? Die vorige Exception verwerfen und die neue auffangen? Sehr schlecht. Vielleicht die neue Exception ignorieren? Auch schlecht. Es gibt einfach keinen Ausweg. Deswegen ist das nicht erlaubt. Wobei die Sprache C++ das nicht verbietet. Wenn ich ein Objekt grundsätzlich auf dem Heap anlege und immer explizit mit delete lösche, kann ich das delete natürlich in einen try-Block packen und die Ausnahme auffangen, wenn der Destruktor fehl schlägt.
-
tntnet schrieb:
Der Codefluß ist dann gerade zwischen einem throw und einem catch, also gerade beim auffangen einer Exception. Der Usercode wirft jetzt eine weitere Exception. Das kann nicht gut gehen.
das kann gut gehen, z.b. wenn exceptions priorisiert sind (so dass handler von niederpriorisierten exceptions von höherpriorisierten exceptions unterbrochen werden können, jedoch nicht umgekehrt). nachdem der hochprio-handler fertig ist, geht's im anderen exception handler weiter. so wie mit 'nested interrupts'. wie regiert c++ denn auf eine exception in einem exception-handler? ich würde wetten, sowas ist, nach alter c++-manier, 'undefined'.
-
Was meinst du mit exception-handler?
sowas?try{ }catch(...){ throw 1; }
ganz normal.
-
~fricky schrieb:
das kann gut gehen, z.b. wenn exceptions priorisiert sind (so dass handler von niederpriorisierten exceptions von höherpriorisierten exceptions unterbrochen werden können, jedoch nicht umgekehrt). nachdem der hochprio-handler fertig ist, geht's im anderen exception handler weiter. so wie mit 'nested interrupts'. wie regiert c++ denn auf eine exception in einem exception-handler? ich würde wetten, sowas ist, nach alter c++-manier, 'undefined'.
ist technisch nicht trivial.
denn ab wann gilt eine exception als behandelt? nach dem catch()? was wenn ich im catch() resourcen kille die bei dem anderen execution tree (von der low priority exception) aktiv sein muessten -> sehr komplex das ganze mit der aktuellen exception mechanik.was aber geht ist die mechanik anzupassen und einen exception stack zu bauen.
eine low priority exception wird geworfen. beim aufraeumen wird eine high priority exception geworfen und wandert auf den exception stack:
wir hantieren nicht mit konkreten exceptions mehr sondern nur mit .top() vom exception stack - wir fangen also die high priority exception irgendwo und es geht weiter solange bis die letzte exception vom stack gepoppt wurde.waere moeglich sowas in c++ zu implementieren - aber wird wohl niemand machen. denn "dtors duerfen nicht werfen" ist einfacher und sinnvoller. denn anders sind transaktionen schwer zu implementieren.
-
Shade Of Mine schrieb:
ist technisch nicht trivial.
aber es dürfte auch nicht sonderlich schwierig sein. was macht c++ eigentlich, wenn zwei oder mehr exceptions gleichzeitig auftreten. gibt es eine definierte reihenfolge, in der sie abgearbeitet werden oder nicht?
Shade Of Mine schrieb:
denn "dtors duerfen nicht werfen" ist einfacher und sinnvoller.
naja, ich weiss nicht, ob das einfacher ist. wer diese regel beherzigt, muss höllisch aufpassen, dass er im destruktor nix aufruft, was exceptions werfen kann. wenn man sich dessen nicht sicher ist, könnte man sich vieleicht damit behelfen, indem man den ganzen code eines destruktors in einen try(...) block packt und eventuelle exceptions sofort abfängt. aber das wird wohl auch nicht gehen, schätze ich mal.
-
~fricky schrieb:
aber es dürfte auch nicht sonderlich schwierig sein. was macht c++ eigentlich, wenn zwei oder mehr exceptions gleichzeitig auftreten. gibt es eine definierte reihenfolge, in der sie abgearbeitet werden oder nicht?
std::unexpected wird aufgerufen was terminate() aufruft.
naja, ich weiss nicht, ob das einfacher ist. wer diese regel beherzigt, muss höllisch aufpassen, dass er im destruktor nix aufruft, was exceptions werfen kann. wenn man sich dessen nicht sicher ist, könnte man sich vieleicht damit behelfen, indem man den ganzen code eines destruktors in einen try(...) block packt und eventuelle exceptions sofort abfängt. aber das wird wohl auch nicht gehen, schätze ich mal.
das aufpassen dass keine exception fliegt ist trivial. da jede release funktion ja nicht werfen darf.
warum es sinn macht ist, weil du damit rollbacks machen kannst. das kannst du nur dann wenn release funktionen nicht fehlschlagen koennen.
-
Warum lasst ihr euch immer in C++-Diskussionen mit Fricky verwickeln?
-
Ich verstehs nicht schrieb:
Warum lasst ihr euch immer in C++-Diskussionen mit Fricky verwickeln?
weil er ab und an doch eine interessante frage stellt der es wert ist nachgegangen zu werden.
-
Shade Of Mine schrieb:
std::unexpected wird aufgerufen was terminate() aufruft.
ahso, und dort kann man sich sicherlich einklinken, eben nicht terminate() aufrufen, sondern stattdessen die anderen exceptions bearbeiten bzw. so ein stackbasiertes system, wie du z.b. vorgeschlagen hast, einbauen.
Shade Of Mine schrieb:
das aufpassen dass keine exception fliegt ist trivial. da jede release funktion ja nicht werfen darf.
vorausgesetzt diese funktionen sind als 'destruktor-tauglich' bekannt, wovon man ja nicht immer ausgehen kann.