wieso gibt es in c++ kein finally?
-
ausnahme-freak schrieb:
asc schrieb:
Bitte behaltet immer in Hinterkopf das C++ auch das Ziel hat effizient und schnell zu sein. Bei C++ wird nicht ohne grund einiges von Laufzeitentscheidungen in die Hand des Entwicklers gelegt. Wenn ich z.B. ausschließen kann das ich über die Indexe eines vectors zugreife, ist eine Prüfung eine unnötige Laufzeitbelastung.
nö, es muss ja nix ständig überprüft werden. eine aktion ist nur gefragt, wenn etwas passiert ist. bisher wird x/0 vom OS ausgewertet, das eine hässliche messagebox aufmacht (falls die exception nicht behandelt wird). sie könnte aber genauso gut an die c++ runtime library weitergereicht werden und als c++ exception im programm wieder auftauchen. ich glaub' msvc kann sowas über diese TRY/EXCEPT macros.

Wie soll das Funktionieren? Natürlich muss bei jedem Zugriff auf einen Zeiger geprüft werden, ob ein Nullpointer vorliegt. Selbiges gilt für das Überschreiten der Boundaries bei Arrays. Jeder Zugriff muss gecheckt werden.
Wie soll er denn sonst wissen, dass was passiert? Kristallkugel?
-
Tachyon schrieb:
Wie soll das Funktionieren? Natürlich muss bei jedem Zugriff auf einen Zeiger geprüft werden, ob ein Nullpointer vorliegt. Selbiges gilt für das Überschreiten der Boundaries bei Arrays. Jeder Zugriff muss gecheckt werden.
Wie soll er denn sonst wissen, dass was passiert? Kristallkugel?nö, das läuft hardwaregestützt ab. CPU, MMU etc. erkennen bus und alignment errors, division durch 0, access violations usw. und lösen einen interrupt aus. das betriebssystem sagt dem programm dann 'schau mal, was du da angestellt hast' und gibt ihm gelegenheit, darauf zu reagieren, indem dessen exception-handler (falls vorhanden) aufgerufen wird. im fall eines c++ programms könnte der exception handler in der c++ runtime lib sitzen, die dann daraus eine c++ exception machen könnte und das c++ programm könnte sie, wie gewohnt, mit einem 'catch' verarbeiten. es geschieht alles automatisch, ohne dass man aktiv irgendwas überprüfen muss.

-
os-freak schrieb:
Tachyon schrieb:
Wie soll das Funktionieren? Natürlich muss bei jedem Zugriff auf einen Zeiger geprüft werden, ob ein Nullpointer vorliegt. Selbiges gilt für das Überschreiten der Boundaries bei Arrays. Jeder Zugriff muss gecheckt werden.
Wie soll er denn sonst wissen, dass was passiert? Kristallkugel?nö, das läuft hardwaregestützt ab. CPU, MMU etc. erkennen bus und alignment errors, division durch 0, access violations usw. und lösen einen interrupt aus. das betriebssystem sagt dem programm dann 'schau mal, was du da angestellt hast' und gibt ihm gelegenheit, darauf zu reagieren, indem dessen exception-handler (falls vorhanden) aufgerufen wird. im fall eines c++ programms könnte der exception handler in der c++ runtime lib sitzen, die dann daraus eine c++ exception machen könnte und das c++ programm könnte sie, wie gewohnt, mit einem 'catch' verarbeiten. es geschieht alles automatisch, ohne dass man aktiv irgendwas überprüfen muss.

Jo, das stimmt. Das könnte mal tatsächlich so machen. Allerdings bedeuten Interrupts im Protected-Mode einen ordentlichen Schlag ins Gesicht des Betriebssystems...
-
hier mal ein beispiel, compiled mit msvc2005 unter win:
#include <stdio.h> #include <windows.h> int divide (int a, int b) { int res = 0; __try { res = a/b; } __except (1) // OS exception handler { throw "divison by zero"; } return res; } int main() { try { int x = divide (5, 0); } catch (char *what) // C++ exception handler { puts (what); } }
-
Die Hardware ist keine magische Black Box. Sobald dein Code auf eine nicht erlaubte Adresse zugreift -> Interrupt -> OS handler -> Exception in deinem Programm: access violation @ 0x00000048 Du kriegst schon eine Exception, wenn du sie willst, aber woher soll klar sein, ob es wegen einem Nullpointer ist?
Und, war das jetzt, weil du nen nullpointer benutzt hast? Ja, wahrscheinlich in diesem Fall. Aber wissen kannst du es schon nicht, du weißt ja nicht, wie dein Programm auf diese Adresse gekommen ist.
Dazu müsste das OS jetzt den Programmzustand ein paar Takte vorher wissen und nachsehen, ob irgendwo 0 + offset gerechnet wird, um die böse Adresse zu bestimmen. Fast unmöglich wird es, wenn du den Zeiger aus irgendner Datenstruktur herholst, in die du ihn 2 Tage vorher reingelegt hast. Du kannst mit Adressen alles machen und ausrechnen. Woher will das OS wissen, dass du die Absicht hattest, dass ein bestimmter Wert nicht hätte 0 sein dürfen?
Ein paar Buzzwords wie MMU und alignment errors helfen da nicht.
Das OS hat keine Ahnung, was ein Programm tun will. Es kann nur dem Programm virtuellen Speicher zur Verfügung stellen und überwachen, dass es die Regeln für jede Speicherseite einhält.
-
Tachyon schrieb:
Allerdings bedeuten Interrupts im Protected-Mode einen ordentlichen Schlag ins Gesicht des Betriebssystems...
schon mal die maus bewegt? solche schläge steckt die kiste locker weg.
Optimizer schrieb:
Die Hardware ist keine magische Black Box. Sobald dein Code auf eine nicht erlaubte Adresse zugreift -> Interrupt -> OS handler -> Exception in deinem Programm: access violation @ 0x00000048 Du kriegst schon eine Exception, wenn du sie willst, aber woher soll klar sein, ob es wegen einem Nullpointer ist?
man kriegt z.b. mitgeteilt, bei welcher adresse der zugriff scheiterte. und wenn die 0 ist, dann kann man sich schon einen reim drauf machen. was nicht geht, sind z.b. exceptions beim überschreiten von arraygrenzen. es kann ja sein, dass sich dahinter speicher befindet, auf den man auch zugriff hat. aber ich finde, man muss nicht so sehr differenzieren. immerhin wär's besser als nix^^
Optimizer schrieb:
Ein paar Buzzwords wie MMU und alignment errors helfen da nicht
wo ist das buzzig? in 'nem coder-board wissen doch die meisten was das heisst.

-
~john schrieb:
hustbaer schrieb:
Finally wäre trotzdem nett.
Finally ist in C++ total überflüssig.
Ich kann mich nur wiederholen: viele Dinge sind in C++ total überflüssig, aber trotzdem da.
-
operatingsystem-freak schrieb:
Tachyon schrieb:
Allerdings bedeuten Interrupts im Protected-Mode einen ordentlichen Schlag ins Gesicht des Betriebssystems...
schon mal die maus bewegt? solche schläge steckt die kiste locker weg.
Optimizer schrieb:
Die Hardware ist keine magische Black Box. Sobald dein Code auf eine nicht erlaubte Adresse zugreift -> Interrupt -> OS handler -> Exception in deinem Programm: access violation @ 0x00000048 Du kriegst schon eine Exception, wenn du sie willst, aber woher soll klar sein, ob es wegen einem Nullpointer ist?
man kriegt z.b. mitgeteilt, bei welcher adresse der zugriff scheiterte. und wenn die 0 ist, dann kann man sich schon einen reim drauf machen.
Die ist aber fast nie 0, weil du den Zeiger i.d.R. dereferenzierst um anschließend auf ein Member zuzugreifen (möglicherweise mehrmals). Deshalb wird zuerst die Adresse, die insgesamt rauskommt, ausgerechnet und dann in den Speicher geschaut, was dort steht. Wenn es in der Nähe von 0 ist, kannst du natürlich vermuten, was die Ursache ist, aber richtig Gewissheit wirst du so nicht kriegen.
Wo siehst du jetzt btw. den Vorteil davon, wenn du es sicher unterscheiden könntest? Gerade null-Pointer sind IMHO die Art von Speicherzugriffsfehler, wo ich nicht lange suchen muss.
-
Tachyon schrieb:
Null-Pointer-Exceptions lassen sich simpel mit einer "Checked Access" Funtion durchführen, oder alternativ mit einer entsprechenden Template-Klasse die das etwas schöner macht:
Das ist eigentlich keine Option. Du kannst nicht einfach ein Projekt im Nachhinein mit solchen Funktion ausstatten. Ausserdem sieht das extrem hässlich aus und verschlechtert die Lesbarkeit.

Tachyon schrieb:
Bei einer Division ist es immer sinnvoller, den Divisor auf 0 zu prüfen, als solche Fehler über ein Laufzeitfehlersystem einmal quer durchs Betriebssystem zu schießen.
Von Fall zu Fall kann man natürlich auf 0 prüfen, sofern dies zum Algorithmus passt. Du hast die eigentliche Thematik aber nicht verstanden. Sofern die Hardware entsprechende Exceptions unterstützt, kostet das nichts an Performance. Erst wenn eine Exception geworfen wird, kostet das Zeit. Und dann ist es sowieso egal. Werden solche Exceptions von der Hardware nicht unterstützt, wird das gleiche wie bei manueller Prüfung gemacht. Und das kostet dann immer Performance. Diese Abstraktion sollte möglichst auf Sprachebene gelöst sein, nicht auf den Anwender abgeschoben werden. Die Möglichkeit, generell solche Prüfungen zu unterbinden oder Hardware Exceptions vom System handeln zu lasen, sollte natürlich trotzdem noch gegeben sein.
Optimizer schrieb:
Die Hardware ist keine magische Black Box. Sobald dein Code auf eine nicht erlaubte Adresse zugreift -> Interrupt -> OS handler -> Exception in deinem Programm: access violation @ 0x00000048 Du kriegst schon eine Exception, wenn du sie willst, aber woher soll klar sein, ob es wegen einem Nullpointer ist?
Betriebssysteme bieten dafür normalerweise eine entsprechende Funktionalität, um das herauszufinden. Unter Windows lässt sich zB mit SEH schon eine ganze Menge machen.
-
groovemaster schrieb:
Betriebssysteme bieten dafür normalerweise eine entsprechende Funktionalität, um das herauszufinden. Unter Windows lässt sich zB mit SEH schon eine ganze Menge machen.
Das ist genauso abstrakt wie alles davor. "Es geht schon" usw. Ich weiß, dass man die böse Adresse in Erfahrung bringen kann. Ich weiß, dass man schätzen kann, ob es auf Grund der Nähe zu 0 dadurch zu Stande gekommen sein könnte, dass man irgendwo einen 0-pointer verwendet hat. Das habe ich alles selber schon geschrieben.
Aber das OS kann es nicht *wissen*. Woher denn? Mein Programm kann *irgendwie* auf die Idee gekommen sein, auf eine bestimmte Adresse zuzugreifen. Und wie gesagt, ich sehe auch kein praktisches Problem dabei, dass es nicht völlig eindeutig ist.