Programiersprache für Anfänger
-
Wenn der Compiler also Exceptions nicht mit SEH implementiert, könnte man dann SEH nicht mit try..catch behandeln? Wie würde das gehen, mit speziellen Handler-Funktionen?
-
Mit dem VS geht's mit __try/__catch: http://www.c-plusplus.net/forum/viewtopic-var-t-is-223116.html
Und/Oder SetUnhandledExceptionFilter, am besten ganzen Thread durchlesen.
-
Bashar schrieb:
Wie würde das gehen, mit speziellen Handler-Funktionen?
dafür gibts spezielle pseudo-keyords __try, __except und __finally. das sieht dann etwa so aus:
__try { *(int*)0 = 1/0; // <-- crash } __except (1) // <-- 1 heisst: in den exception handler springen { puts ("das wäre ihr absturz gewesen"); // <-- exception handler }
-
DEvent schrieb:
Wo ist den das Problem mit einer close() Funktion/Methode?
int main { FileStream stream = FileStream(datei_name); try { stream.write("irgendwelche Daten"); } catch (...) { try { stream.close(); } catch (...) { openDialog("Error:", "Achtung, konnte die Datei 'foo' nicht schliessen, moeglicherweise Datenverlust. Fuehren Sie fsck aus."); } } }
Hier haben wir das Problem, daß im Regenfall die Datei nicht geschlossen wird, sondern nur dann wenn eine Exception gefangen wurde. Zu dem löst Du das Problem der Close Problematik nicht, sondern gibt's nur eine Fehlermeldung aus. Diese Löung gibt es mit Destruktoren ebenfalls. Idealerweise loggt man den Fehler in eine Queue oder eine Datei weg.
DEvent schrieb:
Wie sieht den das ohne eine close() aus:
int main { FileStream stream = FileStream(datei_name); try { stream.write("irgendwelche Daten"); } catch (...) { throw(); } } // hier wird FileStream::~FileStream() aufgerufen, das eine Exception wirft, weil es ein Hardwaredefekt // oder ein korrumpiertes Filesystem gab. Das Programm stuertzt einfach ab, weil man die // Exception nicht fangen kann
Das ist totaler Nonsense. So macht man das bestimmt nicht.
FileStream::~FileStream () throw () { int r = close (this->filedesc_); if (-1 == r) { openDialog("Error:", "Achtung, konnte die Datei 'foo' nicht schliessen, moeglicherweise Datenverlust. Fuehren Sie fsck aus."); // Jetzt steht einem frei das Problem zu ignorieren, zu beheben oder das Programm zu beenden. // Ich wähle hier den harten Weg. std::cerr << "Ein fataler Fehler trat auf, das Programm kann nicht mehr regulär beendet werden!\n"; std::terminate (); } } int main { FileStream stream = FileStream(datei_name); stream.write("irgendwelche Daten"); }
Im Destruktor muß nur noch Geloggt werden, ob ein Fehler beim close des FileStreams auftrat. Mehr machst Du oben auch nicht. Allerdings ließt sich das untere Stückprogramm doch erheblich besser. Allerdings sollte man nicht direkt in main den eigentlichen Arbeitscode aufrufen, sondern in main einen Eception Handler reinsetzen. Wie wurde bereits von audacia beschrieben.
-
~fricky schrieb:
gfhgfh schrieb:
selbst die CPU kennt exceptions. versuch mal durch 0 zu teilen
'ne cpu kann sich sowas auch erlauben. aber stell dir mal vor, c++ würde solche exceptions auch abfangen. dann wären rechenoperationen aber höllisch lahm.
Warum sollte dies langsam sein? Interrupts werden schnell abgearbeitet, und nur im Fehlerfall würde der zusätzliche Code abgearbeitet.
-
~john schrieb:
Warum sollte dies langsam sein?
weil vor vielen rechenoperationen abgefragt werden müsste, ob ein undefiniertes ergebnis entstehen kann (und eine arithmetic-exception o.ä. müsste losgetreten werden).
-
Hi,
In dem Zusammenhang mal ne Frage:
Ich lese hier immer, daß Programmentwicklung mit C# oder Java so viel schneller gehen soll als mit C++.
Irgendwie kann ihc mir das nicht so richtig vorstellen. Man kann doch mit C++ auch die Zeiger weglassen und (zumindest vom Aussehen her) fast identisch wie mit Java oder C# programmieren.
Da ich mir in Java nur mal die Grundzüge angeguckt habe, kann ich dazu aber nicht allzu konkret was sagen.
Andererseits stelle ich mir das Fehlen der STL sowie von Templates bei größeren Projekten als Einschränkung vor.
Vielleicht kann mal ein Java- oder C#-Profi was dazu sagen.
Danke im voraus.Gruß Mümmel
-
In C++ musst Du Dich weitgehen selbst um deinen Speicher kümmern, deswegen die Zeiger. Mann kann nicht ohne weiteres auf Zeiger verzichten und wenn doch, dass verschwendet man Speicher.
Java hat eine Standard-Bibliothek. Statt Templates gibt es da Generics. Das Speicherhandling nimmt dir die Java-Runtime ab.
-
muemmel schrieb:
Ich lese hier immer, daß Programmentwicklung mit C# oder Java so viel schneller gehen soll als mit C++.
Irgendwie kann ihc mir das nicht so richtig vorstellen. Man kann doch mit C++ auch die Zeiger weglassen und (zumindest vom Aussehen her) fast identisch wie mit Java oder C# programmieren.Ich bin zwar beileibe kein Java- und/oder C#-Profi, aber es gibt mehrere Gründe dafür. Zum einen wohl die große Standardbibliothek, die Suche nach externen Bibliotheken beinahe überflüssig machen soll, zum anderen die bessere Tool- und Deployment-Unterstützung.
Edit: Die automatische Speicherverwaltung würde ich nicht als schnelleren Entwicklungsgrund ansehen.
-
[quote="Badestrand"]
muemmel schrieb:
Edit: Die automatische Speicherverwaltung würde ich nicht als schnelleren Entwicklungsgrund ansehen.
Ich schon! Gerade wenn man wenig Erfahrung in C++ hat, muss man sich kaum mit Memory Leaks rumärgern. Die fehleranfälligen Pointer fallen auch weg.
-
asdflllsss schrieb:
In C++ musst Du Dich weitgehen selbst um deinen Speicher kümmern, deswegen die Zeiger. Mann kann nicht ohne weiteres auf Zeiger verzichten und wenn doch, dass verschwendet man Speicher.
Hem, noch nie was von shared_ptr gehört, wie?
asdflllsss schrieb:
Java hat eine Standard-Bibliothek.
Natürlich hat C++ keine...
-
asdflllsss schrieb:
Ich schon! Gerade wenn man wenig Erfahrung in C++ hat, muss man sich kaum mit Memory Leaks rumärgern. Die fehleranfälligen Pointer fallen auch weg.
Definitiv, aber wenn man die Produktivität vergleicht, dann wohl die von "ausgewachsenen" Programmierern. Und ich denke, da wird praktisch gar nicht mehr mit roher Allokierung gearbeitet und falls doch, dann ausreichend gekapselt, so dass man idR keine Speicherlecks mehr hat.
-
Badestrand schrieb:
Zum einen wohl die große Standardbibliothek, die Suche nach externen Bibliotheken beinahe überflüssig machen soll, zum anderen die bessere Tool- und Deployment-Unterstützung.
Hem, in real world projects braucht man aber immer eine externe Library. Wir schleppen in unseren Projekten an die 50 MByte externer JARs mit uns rum, weil die Standard-Library halt nur Standard-Klassen bietet, und man am Ende aber Software individuell entwickelt. Also suche ich mir auch meine individuellen Libs raus, egal ob es einfache Dinge wie log4j ist, oder Axis2 für SOAP, oder itext um PDF zu generieren... ich kenne bei uns kein einziges Projekt, das nicht mind. eine externe JAR hinzufügen muß.
Und bessere Tools... was soll das sein? Es gibt gute Tools, aber wenn man natürlich noch mit VisualC++ 5.0 arbeitet (wie mir letztens ein neuer Kollege erzählt hat, weil er vorher bei SIEMENS ein C++-Projekt hatte), dann soll man auch Java-Tools von Damals als Vergleich nehmen.
-
muemmel schrieb:
Irgendwie kann ihc mir das nicht so richtig vorstellen. Man kann doch mit C++ auch die Zeiger weglassen und (zumindest vom Aussehen her) fast identisch wie mit Java oder C# programmieren.
Ja, in der Theorie kannst du mit C++ fast nach jedem Paradigma programmieren. Nur läßt dich der Compiler sehr oft ins offene Messer rennen. Auch die Tatsache, daß solche Paradigmenverbiegungen gewöhnlich mit massivem Einsatz von Templates umgesetzt werden, vereinfacht die Fehlerdiagnose gerade für Anfänger nicht.
Es kann durchaus von Vorteil sein, wenn gewisse Details nicht als Templates, sondern als Spracheigenschaften umgesetzt werden.
Beispielsweise referenzzählende Zeiger: stattdessen in der Sprache umgesetzt werden. Wenn du in Java, einer .NET-Sprache (GC) oder Delphi (referenzgezählte Interface-Referenzen) eine Referenz falsch benutzt, sagt der Compiler dir das; in C++ landest du mit einer Fehlermeldung, die mit dem tatsächlichen Problem möglicherweise nichts zu tun hat, in der Template-Deklaration.Auch beim Debuggen sind Smart-Pointer ein Krampf. Jeder Step-into auf einer Zeile, in der ein Smart-Pointer benutzt wird, führt dich in den überladenen Operator -> o.ä.
-
asdflllsss schrieb:
Ich schon! Gerade wenn man wenig Erfahrung in C++ hat, muss man sich kaum mit Memory Leaks rumärgern. Die fehleranfälligen Pointer fallen auch weg.
Wenn man Sprachen direkt vergleicht, sollte man von gleichen Wissensstand ausgehen. Wenn man einigermaßen erfahren in den entsprechenden Sprachen ist, greift dein Argument nur bedingt.
Und was "fehleranfälligen Pointer" angeht: Die Häufigsten Fehlermeldungen die ich aus C#/Java kenne sind die Null-Pointer Exceptions. Da man dort sehr wohl mit Zeigern arbeitet (Ja, gewisse Fallstricke werden durch eine Referenzsyntax vermieden, aber im Gegenzug eine höhere Sicherheit vorgegaukelt). Und mir ist egal ob diese dann Null-Referenz oder wie auch immer genannt wird.
Das heißt jetzt aber nicht, das Speicherverwaltung garnicht ins Gewicht fällt.
muemmel schrieb:
Ich lese hier immer, daß Programmentwicklung mit C# oder Java so viel schneller gehen soll als mit C++.
Irgendwie kann ihc mir das nicht so richtig vorstellen.Da ich in den Sprachen C++/Java/C# meine Erfahrungen habe, meine Meinung (begrenze mich aber aufgrund der aktuelleren C++/C# Kenntnisse auf diese beiden im Vergleich):
1. Framework
In C# ist das mitgelieferte Framework umfassender und weitgehend auch leichter zu bedienen als alles, was ich von C++ kenne. Zudem ist der Stil in .Net recht einheitlich, in C++ muss man häufig für den gleichen Umfang mehrere Bibliotheken mit unterschiedlichen Stil verwenden (Auch diese Stilunterschiede kosten Zeit).2. Die IDE-Unterstützung
a) Allgemein
Ich würde sagen im Grundsatz sind moderne IDEs in allen Sprachen durchaus mächtig. Die Unterstützung wird aber auch durch Fähigkeiten der Sprache besser...
b) Unterstützung dank Reflektion
Was in C++ viel Analyseaufwand bei der Toolunterstützung kostet, bekommt man in Sprachen mit Reflektion teilweise fast geschenkt. Codevervollständigungen etc. die ja durchaus auch die Arbeit beschleunigen können, lassen sich leichter implementieren, was auch die Verbreitung ebensolcher Bestandteile erhöht.
c) Bibliotheksunterstützung
Zumeist hat man auch eine bessere Unterstützung der Bibliotheken, weil man selten externe Bibliotheken braucht. Häufig reicht in C# und Java bereits das mitgelieferte aus, wodurch die Dokumentation, die direkte IDE-Unterstützung, Grafikdesigner etc. eher zum Standard gehören als in C++.3. Beschleunigung dank Codereduzierung und Vereinfachungen
Wenn ich ein und das selbe in C++ sowie C# umsetzen will, stelle ich zumindestens fest, das ich in C# meist weniger Code für die gleiche Funktionalität brauche. Es gibt hier auch Ausnahmen, aber über das Projekt gesehen gehe ich - je nach Art des Projektes - von einer Einsparung von mindestens 25% und mehr.
Um so komplexer das Projekt ist - Grafik, Mehrschichtenarchitektur, etc., um so höher ist der Codeunterschied nach meiner Erfahrung.
Das liegt zum Teil aber auch daran, das vieles vereinfacht dargestellt wird, weniger Sonderfälle (dafür natürlich auch einige "Stellschrauben" weniger) existieren.Man erkäuft sich natürlich auch Nachteile mit Java/C#. Java/C#-Programme in gleichen Funktionsumfang wie C++ Programme haben in den überwiegenden Fällen, mit den ich konfrontiert wurde, weniger Performance, höhere Speicheranforderungen, längere Startzeiten... Dies heißt aber nicht das alle Java/C#-Programme automatisch langsam sind, wobei im direkten Vergleich (zumindestens bei Standardsoftware die ich kenne), das native Programm den Vorsprung hat.
cu André
-
asc schrieb:
Zudem ist der Stil in .Net recht einheitlich, in C++ muss man häufig für den gleichen Umfang mehrere Bibliotheken mit unterschiedlichen Stil verwenden (Auch diese Stilunterschiede kosten Zeit).
Nicht zu knapp.
Vermutlich ist das eines der größten Defizite dieser Sprache: eine stilistische und architektonische Basis, wie sie in Java, C# oder Delphi allgemein anerkannt ist, existierte für C++ nie. Beispielsweise gibt es in jeder halbwegs produktiven Umgebung mehrere String-Typen, unter anderem, weil std::string ein evasiver Minimalismus von einer Stringklasse ist. Und auch sonst sind die Unausgegorenheiten von Standard-C++ kaum zu zählen: es gibt in der Standardbibliothek keine tauglichen Smart-Pointer, keine taugliche String-Formatierungsfunktion, es gibt kein klar trennendes Modulkonzept, keine einheitliche Implementation von Delegaten, nur die mehr als minimalistische RTTI, etc. pp.
Die unvermeidliche Folge: unzählige Individuallösungen, sämtlich inkompatibel.
-
asc schrieb:
Und was "fehleranfälligen Pointer" angeht: Die Häufigsten Fehlermeldungen die ich aus C#/Java kenne sind die Null-Pointer Exceptions. Da man dort sehr wohl mit Zeigern arbeitet (Ja, gewisse Fallstricke werden durch eine Referenzsyntax vermieden, aber im Gegenzug eine höhere Sicherheit vorgegaukelt). Und mir ist egal ob diese dann Null-Referenz oder wie auch immer genannt wird.
Wenn man in C++ einen Nullpointer (oder Zeiger ins Nirvana) derefenziert, bekommt man eine Schutzverletzung, Segmentation Fault, Core Dump, was auch immer (jedenfalls war das so, als ich mich noch damit beschäftigen durfte).
In Sprachen mit Managed Code kann ich solche Fehler auffangen und behandeln. Ich kann ein Fehlerreport generieren, wo drin steht, welche Variable in welcher Methode welcher Klasse (mit Zeilennummer) null war. Den Report kann man dann zusammen mit einem Screenshot der Anwendung, den letzten 100 Zeilen des Logfiles und einem Kommentar des Anwenders an den Support schicken und sofort mit dem Bugfixing anfangen. Ein enormer Vorteil.
Von den Möglichkeiten des (Remote-)Debugging mit Hot-Code-Replacement ganz zu schweigen.Bezogen auf Java: Vorteilhaft ist auch das Angebot an Applicationservern (Tomcat, JBoss, etc) und unterstützenden Frameworks (Spring, Hibernate).
-
tfa schrieb:
In Sprachen mit Managed Code kann ich solche Fehler auffangen und behandeln. Ich kann ein Fehlerreport generieren, wo drin steht, welche Variable in welcher Methode welcher Klasse (mit Zeilennummer) null war.
das kann man auch mit sprachen die nativen code erzeugen :xmas1:
-
tfa schrieb:
Wenn man in C++ einen Nullpointer (oder Zeiger ins Nirvana) derefenziert, bekommt man eine Schutzverletzung, Segmentation Fault, Core Dump, was auch immer (jedenfalls war das so, als ich mich noch damit beschäftigen durfte).
Wie auch schon von sothis_ erwähnt, muss das nicht sein.
Ich habe, als ich noch mit einen Compiler gearbeitet habe der so gut wie von keiner Bibliothek mehr unterstützt wurde, Smartpointern selbst geschrieben. Und diese hatten, die auch von Java und C# üblichen NULL-Prüfungen, sowie das Exceptionhandling eingebaut.Es kommt immer darauf an wie man C++ verwendet, und was man für Zielsetzungen hat.
tfa schrieb:
In Sprachen mit Managed Code kann ich solche Fehler auffangen und behandeln.
Besser ist es, wenn man von vorne herein auch die Exception ausschließen kann. Und NULL-Prüfungen kann man auch in C++ machen.
tfa schrieb:
Bezogen auf Java: Vorteilhaft ist auch das Angebot an ... unterstützenden Frameworks (Spring, Hibernate).
Das kann wieder genau ein Nachteil sein. Sicher, das Angebot von kompatiblen Bibliotheken/Frameworks ist ein Vorteil, aber gleichzeitig auch ein Nachteil (unterschiedliche Stile etc.). Dies ist beispielsweise unter C++ ein großer Vor-/Nachteil: Die extreme Anzahl unterschiedlicher.
cu André
-
asc schrieb:
Und was "fehleranfälligen Pointer" angeht: Die Häufigsten Fehlermeldungen die ich aus C#/Java kenne sind die Null-Pointer Exceptions. Da man dort sehr wohl mit Zeigern arbeitet (Ja, gewisse Fallstricke werden durch eine Referenzsyntax vermieden, aber im Gegenzug eine höhere Sicherheit vorgegaukelt). Und mir ist egal ob diese dann Null-Referenz oder wie auch immer genannt wird.
Naja ok, Du musst ein neues Objekt mit new anlegen, schön. Viel mehr gibt es nicht zu tun. Die Garbage Collection kümmert sich um den Rest.