[C++] Wann müssen Ausnahmetypen polymorph sein?

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

[C++] Wann müssen Ausnahmetypen polymorph sein?

Beitrag von Krishty »

Hi,

ich habe gerade gesehen, dass ich meiner Exception-Klasse einen virtuellen Destruktor hinzugefügt habe. Wahrscheinlich, weil das alle so machen und ich nicht weiter drüber nachgedacht habe. Jetzt ziehe ich das erneut in Betracht, und frage mich: Wozu? Unter welchen Umständen braucht man das überhaupt?

Fallen euch welche ein, oder kann ich die Virtual Function Tables sparen und beruhigt überall nur noch POD schmeißen?

Gruß, Ky
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: [C++] Wann müssen Ausnahmetypen polymorph sein?

Beitrag von Chromanoid »

Wenn jemand oder Du Funktionalität erweitern und spezifischere Exceptions werfen möchte ohne überall die Zugriffe/catch-Blöcke anpassen zu müssen.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Wann müssen Ausnahmetypen polymorph sein?

Beitrag von Krishty »

Vielleicht ein kleines Missverständnis: In C++ sind polymorphe Typen diejenigen, die virtuelle Methoden besitzen. Ich kann Vererbung auch ohne virtuelle Methoden nutzen; dann sind die Ausnahmetypen in diesem Sinne nicht mehr polymorph.

Wiedemauchsei – Vererbung ist bei Ausnahmen IMO sowieso nur fürs Filtern sinnvoll, und das geht auch ohne virtuelle Methoden (der Compiler sorgt für passende Kopien und Zerstörung gemäß des tatsächlichen Typs). Ich entferne die Polymorphie einfach mal und prüfe, ob was Unerwartetes passiert.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: [C++] Wann müssen Ausnahmetypen polymorph sein?

Beitrag von Chromanoid »

Mmh aber ist nicht genau die Polymorphie das, was einen bei den Exceptions interessiert. Also sowas hier:

Code: Alles auswählen

#include <iostream>
#include <string>

using namespace std;

class base_exception
{
public:
	virtual string reason() {
		return "Fehler";
	}
};

class my_exception1 : public base_exception
{
	string errorInFile;
public:
	my_exception1(string errorInFile):base_exception() {
		this->errorInFile=errorInFile;
	}
	string reason(){
		return getErrorFile();
	}
	string getErrorFile() {
		return errorInFile;
	}
};

void throwIt(int i) {
	if(i==0)
		throw base_exception();
	throw my_exception1("Datei1.txt");
}

int main()
{
	try {
		throwIt(0);
	}
	catch(base_exception &ex) {		
		cout << typeid(ex).name() << ": " << ex.reason() << endl;
	}
	try {
		throwIt(1);
	}
	catch(base_exception &ex) {		
		cout << typeid(ex).name() << ": " << ex.reason() << endl;
	}
	return 0;
}
Wenn ich da das virtual weglasse, dann wird ja immer reason von base_exception aufgerufen. Ich müsste extra my_exception1 vorher fangen um den erweiterten Fehlertext zu bekommen. Auch das typeid gibt ohne vtable das falsche zurück bzw. die spezielle Typinformation geht einfach verloren oder nicht? Besonders beim Loggen oder so stelle ich mir das recht unbequem vor, wenn man Ausnahmen nicht generisch in Text umwandeln kann. Oder übersehe ich da was? Ich programmiere C++ ungefähr einmal im Jahr :)
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Wann müssen Ausnahmetypen polymorph sein?

Beitrag von Krishty »

Chromanoid hat geschrieben:Wenn ich da das virtual weglasse, dann wird ja immer reason von base_exception aufgerufen. Ich müsste extra my_exception1 vorher fangen um den erweiterten Fehlertext zu bekommen. Auch das typeid gibt ohne vtable das falsche zurück bzw. die spezielle Typinformation geht einfach verloren oder nicht?
Ja genau.
Besonders beim Loggen oder so stelle ich mir das recht unbequem vor, wenn man Ausnahmen nicht generisch in Text umwandeln kann. Oder übersehe ich da was? Ich programmiere C++ ungefähr einmal im Jahr :)
Logging / Debugging sollte direkt beim Auftreten des Fehlers stattfinden und nicht beim Abfangen, oder?

Ich habe bisher keinen Fall gehabt, wo mich die Textrepräsentation einer Ausnahme interessiert hätte. Falls der Anwender sie DOCH mal brauchen sollte (ich habe aber von keinen Anwendern gehört, die Technik-Blabla-Fehlermeldungen mögen), muss ich sie sowieso beim Abfangen formatieren statt beim Werfen, weil ich über die Präsentationsart nicht entscheiden kann, während der Fehler gerade auftritt. (Darum dirigiert man ja nach oben – weil man nicht weiß, wie man weiter verfahren soll.)

Will man also irgendeinen Datei konnte nicht geöffnet werden weil-Schnickschnack ausgeben, muss das Fangen sowieso die CouldNotOpenFileException kennen und entscheiden, ob und wie ihr .reason ausgewertet und präsentiert wird: Datei in Benutzung; schließen Sie "foo" und probieren Sie es erneut! mit Wiederholen-Knopf für ERROR_FILE_IN_USE? Netzwerk nicht verfügbar!-Fehlermeldung für ERROR_INVALID_NETWORK_PATH? Eine Message Box mit kryptischen Fehlercodes für den Rest? Oder direkt ein XML-Dump vom letzten Fehler der WinAPI, wenn eine Zugriffsverletzung aufgetaucht ist? In welcher Sprache mit welchem Zeichensatz und welcher Formatierung? Polymorphie in der Ausnahmeklasse bringt mir dabei rein garnichts.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: [C++] Wann müssen Ausnahmetypen polymorph sein?

Beitrag von Chromanoid »

Ich sehe das natürlich mit einer Java Brille. Ich bin außerdem ein exzessiver Bibliotheken Nutzer.

Wenn ich jetzt also eine Bibliothek XY nutze, dann bin ich daran interessiert, dass alle Exceptions die dort geworfen werden erst einmal von einer speziellen "XYException" ableiten (oder sie reichen durch, wenn es nicht zu spezielle sind) und einen sinnvollen Fehlertext angeben. Nicht für den Nutzer sondern vor allem für mich als Entwickler. Das Logging soll zwar ruhig schon in Bibliothek XY stattfinden, aber wenn ich jetzt als Entwickler anders logge, dann möchte ich die Möglichkeit haben jede XYException, die mir um die Ohren fliegt, in einen sinnvollen Text umzuwandeln und zwar ohne darüber nachzudenken, was da alles kommen könnte.

Als Entwickler möchte ich nun eine eigene Bibliothek entwerfen, die die Funktionalität von XY kapselt und noch ein paar andere Dinge tut. Ich benutze außerdem noch die Bibliothek UV mit "UVExceptions". Checked exceptions oder nicht, ich möchte alles was aus der Bibliothek XY und UV kommt erst einmal kapseln und in eine für andere Entwickler einfacher zu verstehende Exception umbauen. Die ursprüngl. Exceptions werden in der umschließenden Exception gespeichert und können bei Bedarf ausgelesen werden. Letzteres wird glaube ich auch schwierig ohne Typinformation.

BTW sind Ausnahmen nicht so selten, dass man sich die Polymorphie ohne Probleme leisten kann? Ich meine so komplex sollten die Exception-Hierarchien und Funktionen nicht sein und man gewinnt bzw. behält :) so viele Möglichkeiten.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Wann müssen Ausnahmetypen polymorph sein?

Beitrag von Krishty »

Chromanoid hat geschrieben:BTW sind Ausnahmen nicht so selten, dass man sich die Polymorphie ohne Probleme leisten kann?
Eben weil sie so selten sind sollten sie nicht unnötige Seiten belegen.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C++] Wann müssen Ausnahmetypen polymorph sein?

Beitrag von BeRsErKeR »

Krishty hat geschrieben:Ich habe bisher keinen Fall gehabt, wo mich die Textrepräsentation einer Ausnahme interessiert hätte. Falls der Anwender sie DOCH mal brauchen sollte (ich habe aber von keinen Anwendern gehört, die Technik-Blabla-Fehlermeldungen mögen), muss ich sie sowieso beim Abfangen formatieren statt beim Werfen, weil ich über die Präsentationsart nicht entscheiden kann, während der Fehler gerade auftritt. (Darum dirigiert man ja nach oben – weil man nicht weiß, wie man weiter verfahren soll.)
Bei manchen Exception-Klassen kannst du nur beim Werfen/Erzeugen formatieren. Denk nur mal an eine Exception die z.B. intern eine Zeilennummer speichert. Wenn du die Meldung dann als "<Zeilennummer>: <Fehlertext>" ausgeben willst, könntest du das beim Fangen nur dann realisieren, wenn du diesen speziellen Exception-Typ fängst. Wenn du aber nur std::exception fängst, dann hast du keine einfache Möglichkeit da im Nachhinein noch korrekt zu formatieren. Klar wäre hier der schönere Weg (wie auch allgemein) alle möglichen Exception-Typen direkt zu fangen. Ob das aber immer möglich und auch nötig ist, ist eine andere Sache. Man weiß auch nicht immer (gerade wenn es um 3rd party libs geht) welche Exceptions da fliegen können. Außer die Docu ist sehr gut, was eher selten der Fall ist.

Ich finde die Möglichkeit what() zu überladen daher schon sehr sinnvoll.

Übrigens kenne ich einige Programmierer, die sehr viel über Exceptions lösen, vorallem auch Fehler, die andere Programmierer als Rückgabewert abarbeiten. Gerade für Exceptions, die man selbst schreibt sind die Nachrichten oft sehr hilfreich, vorallem wenn Sie nicht nur hardcoded Text beinhalten, sondern auch andere Werte (Zeilennummer, IDs, Schleifenindex, Dateiname, etc). Besonders hier ist dann das Überladen sehr entscheidend.

Für mich persönlich sind die Nachrichten von Exceptions das Wichtigste. Viel wichtiger als der Typ der Exception. Wenn diese nämlich aussagekräftig und inhaltsvoll sind, dann erspart das oft sehr viel Debugging und Fehlersuche.
Krishty hat geschrieben:Will man also irgendeinen Datei konnte nicht geöffnet werden weil-Schnickschnack ausgeben, muss das Fangen sowieso die CouldNotOpenFileException kennen und entscheiden, ob und wie ihr .reason ausgewertet und präsentiert wird: Datei in Benutzung; schließen Sie "foo" und probieren Sie es erneut! mit Wiederholen-Knopf für ERROR_FILE_IN_USE? Netzwerk nicht verfügbar!-Fehlermeldung für ERROR_INVALID_NETWORK_PATH? Eine Message Box mit kryptischen Fehlercodes für den Rest? Oder direkt ein XML-Dump vom letzten Fehler der WinAPI, wenn eine Zugriffsverletzung aufgetaucht ist? In welcher Sprache mit welchem Zeichensatz und welcher Formatierung? Polymorphie in der Ausnahmeklasse bringt mir dabei rein garnichts.
Eben nicht. Wenn die CouldNotOpenFileException ihre Nachricht gut aufbereitet und z.B. reason für den Anwender verständlich und menschenlesbar ausgibt, kann man auch einfach allgemein alle Exceptions fangen und würde dann dennoch wissen, was schief lief. Klar wenn du mit reason dann noch im Programm was machen willst, dann musst du spezifisch fangen. DIe Frage ist aber ob du das an jeder Stelle benötigst. Denn oftmals brauchst du diesen Fall nicht und willst nur Informationen haben/anzeigen. Zeilennummern sind z.B. nur als Information nützlich und benötigen beim Fangen keinerlei zusätzliche Auswertung.
Ohne Input kein Output.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Wann müssen Ausnahmetypen polymorph sein?

Beitrag von Krishty »

BeRsErKeR hat geschrieben:Übrigens kenne ich einige Programmierer, die sehr viel über Exceptions lösen, vorallem auch Fehler, die andere Programmierer als Rückgabewert abarbeiten. Gerade für Exceptions, die man selbst schreibt sind die Nachrichten oft sehr hilfreich, vorallem wenn Sie nicht nur hardcoded Text beinhalten, sondern auch andere Werte (Zeilennummer, IDs, Schleifenindex, Dateiname, etc). Besonders hier ist dann das Überladen sehr entscheidend.

Für mich persönlich sind die Nachrichten von Exceptions das Wichtigste. Viel wichtiger als der Typ der Exception. Wenn diese nämlich aussagekräftig und inhaltsvoll sind, dann erspart das oft sehr viel Debugging und Fehlersuche.
Dann missbrauchst du sie. Ausnahmen sind nicht zum Debugging da; dafür gibt es Logging und Haltepunkte.
BeRsErKeR hat geschrieben:
Krishty hat geschrieben:Will man also irgendeinen Datei konnte nicht geöffnet werden weil-Schnickschnack ausgeben, muss das Fangen sowieso die CouldNotOpenFileException kennen und entscheiden, ob und wie ihr .reason ausgewertet und präsentiert wird: Datei in Benutzung; schließen Sie "foo" und probieren Sie es erneut! mit Wiederholen-Knopf für ERROR_FILE_IN_USE? Netzwerk nicht verfügbar!-Fehlermeldung für ERROR_INVALID_NETWORK_PATH? Eine Message Box mit kryptischen Fehlercodes für den Rest? Oder direkt ein XML-Dump vom letzten Fehler der WinAPI, wenn eine Zugriffsverletzung aufgetaucht ist? In welcher Sprache mit welchem Zeichensatz und welcher Formatierung? Polymorphie in der Ausnahmeklasse bringt mir dabei rein garnichts.
Eben nicht. Wenn die CouldNotOpenFileException ihre Nachricht gut aufbereitet und z.B. reason für den Anwender verständlich und menschenlesbar ausgibt
Du bist nicht auf den Absatz eingegangen: „für den Anwender verständlich und menschenlesbar“? Welche Sprache? Muss jede Ausnahme, die geworfen werden könnte, für jede Sprache und jede Kultur Übersetzungs- und Formatierungsroutinen beinhalten? Komma statt Dezimalpunkt, rechts-zu-links-Textfluss, Übersetzungen? Und muss sie diese Formatierung jedes Mal zur Verfügung stellen; auch, wenn ich das nicht benutze und es mich nicht interessiert? Nennst du das Kapselung?
… kann man auch einfach allgemein alle Exceptions fangen und würde dann dennoch wissen, was schief lief.
Wer würde das wissen? Das Programm? Das kann menschverfasste Texte nicht interpretieren. Der Programmierer? Der kriegt nichts mit, wenn beim Endbenutzer eine Ausnahme fliegt. Der Anwender? Der weiß nicht, was das Netzlaufwerk ist, von dem die Meldung auf dem Bildschirm redet.
Klar wenn du mit reason dann noch im Programm was machen willst, dann musst du spezifisch fangen. DIe Frage ist aber ob du das an jeder Stelle benötigst. Denn oftmals brauchst du diesen Fall nicht und willst nur Informationen haben/anzeigen.
Halb richtig: Oftmals brauche ich nichts Spezielles fangen sondern möchte einfach nur abbrechen und Ausgabe interessiert mich nicht.
Zeilennummern sind z.B. nur als Information nützlich und benötigen beim Fangen keinerlei zusätzliche Auswertung.
Wenn du einen Compiler schreibst, möchtest du z.B. die Position eines Syntaxfehlers auswerten und den Fehler in der IDE rot unterstrichen darstellen. Wie denn, ohne Zeilennummern auszuwerten?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: [C++] Wann müssen Ausnahmetypen polymorph sein?

Beitrag von Chromanoid »

Was ist denn mit Ausnahmen von Bibliotheken deren Code Du nicht hast? Was ist wenn man ein Produkt beim Kunden hat, der eben nicht einen Debugger installiert hat und ständig nicht reproduzierbare Bugs entdeckt? Klar kann man das auch "loggen" bevor die Exception geschmissen wird, aber das ist halt aufwendig, besonders wenn man alle möglichen Exceptions abfangen muss. Es geht hier doch nur um Optimierung nicht um bad smell!? Bei Fehlern will ich soviele Informationen wie möglich mit so wenig Aufwand wie möglich bekommen, da ist Optimierung auf Kosten der Bequemlichkeit IMO fehl am Platz.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Wann müssen Ausnahmetypen polymorph sein?

Beitrag von Krishty »

Chromanoid hat geschrieben:Was ist denn mit Ausnahmen von Bibliotheken deren Code Du nicht hast?
Wenn ich eine fremde Bibliothek nutze, muss ich mich auch an ihre Regeln halten und muss einknicken.
Was ist wenn man ein Produkt beim Kunden hat, der eben nicht einen Debugger installiert hat und ständig nicht reproduzierbare Bugs entdeckt?
Abstürzen lassen und den Crash Dump analysieren?
Klar kann man das auch "loggen" bevor die Exception geschmissen wird, aber das ist halt aufwendig, besonders wenn man alle möglichen Exceptions abfangen muss.
Es ist doch weniger aufwendig als, jede Ausnahme eine Textbeschreibung ausspucken zu lassen, oder? Weil wir uns jetzt an minimale Formatierung und eine einzige Sprache halten können; die Benutzeroberfläche interessiert das ja nicht.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: [C++] Wann müssen Ausnahmetypen polymorph sein?

Beitrag von Chromanoid »

Krishty hat geschrieben:
Klar kann man das auch "loggen" bevor die Exception geschmissen wird, aber das ist halt aufwendig, besonders wenn man alle möglichen Exceptions abfangen muss.
Es ist doch weniger aufwendig als, jede Ausnahme eine Textbeschreibung ausspucken zu lassen, oder? Weil wir uns jetzt an minimale Formatierung und eine einzige Sprache halten können; die Benutzeroberfläche interessiert das ja nicht.
Naja man will ja nicht jede Exception loggen. Manchmal möchte man das auch erst auf einer bestimmten Ebene, auf der man dann den catch-Block auffächern muss, weil Polymorphie nicht eingesetzt wurde. Die Exception funktioniert dann als "Lognachricht-Fehlerinformations"-Container, der bei Bedarf ausgespuckt werden kann.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Wann müssen Ausnahmetypen polymorph sein?

Beitrag von Krishty »

Und das nervt mich an dem ganzen Konzept auch: Anstatt die Informationen dort zu verarbeiten, wo der Fehler auftritt, verpackt man sie erstmal in einen Container, reißt den halben Aufrufstapel ab, kopiert die Daten an eine Stelle hundert Tausend Zeilen entfernt und versucht dann nachträglich, noch was zu analysieren. Möglichkeiten, die Ausführung fortzusetzen, bietet C++ auch nicht. Das stinkt mir langsam alles.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: [C++] Wann müssen Ausnahmetypen polymorph sein?

Beitrag von Chromanoid »

Also wenn man volle Kontrolle über den Code hat, macht das "Informationen dort zu verarbeiten, wo der Fehler auftritt" ja noch Sinn, weil man sich da noch entscheiden kann. Sobald das ganze aber in einer externen Bibliothek geworfen wird, möchte man doch lieber selbst entscheiden wo das ganze landet?
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Wann müssen Ausnahmetypen polymorph sein?

Beitrag von Krishty »

Ja; das war jetzt eine Mischung aus Brainfart und Rant – entschuldige …
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C++] Wann müssen Ausnahmetypen polymorph sein?

Beitrag von BeRsErKeR »

Krishty hat geschrieben:
BeRsErKeR hat geschrieben:Übrigens kenne ich einige Programmierer, die sehr viel über Exceptions lösen, vorallem auch Fehler, die andere Programmierer als Rückgabewert abarbeiten. Gerade für Exceptions, die man selbst schreibt sind die Nachrichten oft sehr hilfreich, vorallem wenn Sie nicht nur hardcoded Text beinhalten, sondern auch andere Werte (Zeilennummer, IDs, Schleifenindex, Dateiname, etc). Besonders hier ist dann das Überladen sehr entscheidend.

Für mich persönlich sind die Nachrichten von Exceptions das Wichtigste. Viel wichtiger als der Typ der Exception. Wenn diese nämlich aussagekräftig und inhaltsvoll sind, dann erspart das oft sehr viel Debugging und Fehlersuche.
Dann missbrauchst du sie. Ausnahmen sind nicht zum Debugging da; dafür gibt es Logging und Haltepunkte.
BeRsErKeR hat geschrieben:
Krishty hat geschrieben:Will man also irgendeinen Datei konnte nicht geöffnet werden weil-Schnickschnack ausgeben, muss das Fangen sowieso die CouldNotOpenFileException kennen und entscheiden, ob und wie ihr .reason ausgewertet und präsentiert wird: Datei in Benutzung; schließen Sie "foo" und probieren Sie es erneut! mit Wiederholen-Knopf für ERROR_FILE_IN_USE? Netzwerk nicht verfügbar!-Fehlermeldung für ERROR_INVALID_NETWORK_PATH? Eine Message Box mit kryptischen Fehlercodes für den Rest? Oder direkt ein XML-Dump vom letzten Fehler der WinAPI, wenn eine Zugriffsverletzung aufgetaucht ist? In welcher Sprache mit welchem Zeichensatz und welcher Formatierung? Polymorphie in der Ausnahmeklasse bringt mir dabei rein garnichts.
Eben nicht. Wenn die CouldNotOpenFileException ihre Nachricht gut aufbereitet und z.B. reason für den Anwender verständlich und menschenlesbar ausgibt
Du bist nicht auf den Absatz eingegangen: „für den Anwender verständlich und menschenlesbar“? Welche Sprache? Muss jede Ausnahme, die geworfen werden könnte, für jede Sprache und jede Kultur Übersetzungs- und Formatierungsroutinen beinhalten? Komma statt Dezimalpunkt, rechts-zu-links-Textfluss, Übersetzungen? Und muss sie diese Formatierung jedes Mal zur Verfügung stellen; auch, wenn ich das nicht benutze und es mich nicht interessiert? Nennst du das Kapselung?
Ich nutze die Exceptions ja nicht spezifisch für das Debuggen. Ich habe aber oft den Fall das meine Software von Anwendern verwendet wird. Und wenn dann eine Exception fliegt, ist es schon wichtig, dass sie aussagekräftige Informationen bereitstellt.

Das mit dem "für den Anwender" ist natürlich nicht ganz korrekt. Ich bin da eher von mir als Entwickler ausgegangen während der Test-Phase. Denk dir das "für den Anwender" einfach weg oder ersetze es durch "für einen Menschen". Es ist mMn nicht wichtig ob das übersetzt wird oder perfekt formatiert ist, denn der Anwender muss diese Informationen nicht unbedingt soweit verstehen, dass er sofort die Lösung kennt. Wichtig ist, dass er entweder mir (dem Entwickler) einen Screenshot des Fehlers schicken oder im Internet nach dieser Meldung suchen kann und so zu Hilfe kommt. Dabei ist es übrigens egal ob du die Informationen der Exception in eine Log-Datei schiebst oder über eine MessageBox anzeigst. Eine Log-Datei wirst du wohl auch nicht sprachabhängig machen. Ich sehe übrigens auch nicht, was deiner Meinung nach Exceptions und Logging gegenseitig ausschließt.

Krishty hat geschrieben:
… kann man auch einfach allgemein alle Exceptions fangen und würde dann dennoch wissen, was schief lief.
Wer würde das wissen? Das Programm? Das kann menschverfasste Texte nicht interpretieren. Der Programmierer? Der kriegt nichts mit, wenn beim Endbenutzer eine Ausnahme fliegt. Der Anwender? Der weiß nicht, was das Netzlaufwerk ist, von dem die Meldung auf dem Bildschirm redet.
Klar wenn du mit reason dann noch im Programm was machen willst, dann musst du spezifisch fangen. DIe Frage ist aber ob du das an jeder Stelle benötigst. Denn oftmals brauchst du diesen Fall nicht und willst nur Informationen haben/anzeigen.
Halb richtig: Oftmals brauche ich nichts Spezielles fangen sondern möchte einfach nur abbrechen und Ausgabe interessiert mich nicht.
Zeilennummern sind z.B. nur als Information nützlich und benötigen beim Fangen keinerlei zusätzliche Auswertung.
Wenn du einen Compiler schreibst, möchtest du z.B. die Position eines Syntaxfehlers auswerten und den Fehler in der IDE rot unterstrichen darstellen. Wie denn, ohne Zeilennummern auszuwerten?
Ich als Entwickler würde das wissen bzw. ich könnte damit schneller die Ursache finden. Wieso kriegt der nix mit wenn beim Anwender eine Exception fliegt? Im Normalfall klingelt da innerhalb von 5 Minuten das Telefon oder man hat eine Mail mit einem Screenshot im Posteingang. Oder aber es gibt projektspezifische Foren wo man diese Meldung posten kann. Natürlich gibt es immer Ausnahmen. Windows' berühmte Meldungen ála "Völlig unerwarteter Ausnahmefehler 0x81680085" bringen natürlich niemandem etwas. Eine Meldung wie "Namespace::Klasse::Funktion: Die Variable x ist zu groß (Datei: foo.bar)" können aber schon hilfreich sein um entweder Bugs im Programm, unsachgemäßen Gebrauch oder falsche Inputdaten zu identifizieren. Gerade da wo man nicht Debuggen kann (z.B. beim Anwender). Und wenn man dann noch den Stack-Trace etc. ausgeben kann hat man natürlich noch mehr Vorteile.

Wenn du nur fangen willst und dich die Ausgabe nicht interessiert dann musst du sie nicht auswerten bzw. kannst hier doch einfach etwas nicht-polymorphes schmeißen. Du bist doch nicht gezwungen das Konzept oder überhaupt std::exception zu nutzen. Schmeißen kannst du doch was du möchtest. Ich dachte dir geht es um "wann ist das sinnvoll?". Das man es nicht immer braucht ist klar. Aber ich brauch es oft.

Mit dem Compiler hast du recht. Ich dachte da an etwas anderes, nämlich Schema-Prüfung und Transformation (also grob gesagt Analyse/Auswertung) von XML-Dateien, da ich gerade viel damit am Hut habe. Hier ist die Datei in der Regel nicht irgendwo geöffnet, sondern wird nur im Speicher gehalten. Da springt man in der Regel nirgends hin und will mit der Information "Zeilennummer" dann in einem XML-Editor nachschauen.
Ohne Input kein Output.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C++] Wann müssen Ausnahmetypen polymorph sein?

Beitrag von BeRsErKeR »

Krishty hat geschrieben:
Was ist wenn man ein Produkt beim Kunden hat, der eben nicht einen Debugger installiert hat und ständig nicht reproduzierbare Bugs entdeckt?
Abstürzen lassen und den Crash Dump analysieren?
Was ist hier für dich der Crash Dump? Das kann genauso gut eine Exception realisieren, aber so, dass das Programm wenigstens noch sauber ausgeht. Ich verstehe nicht so ganz wieso das eine das andere ausschließen sollte. Wo bekommst du denn deinen Crash Dump her?

Krishty hat geschrieben:
Klar kann man das auch "loggen" bevor die Exception geschmissen wird, aber das ist halt aufwendig, besonders wenn man alle möglichen Exceptions abfangen muss.
Es ist doch weniger aufwendig als, jede Ausnahme eine Textbeschreibung ausspucken zu lassen, oder? Weil wir uns jetzt an minimale Formatierung und eine einzige Sprache halten können; die Benutzeroberfläche interessiert das ja nicht.
Du legst die Textbeschreibung beim Schmeißen an, also dort wo der Fehler auftritt und wo du genau weißt was das Problem ist. An anderer Stelle ist es nicht oder nur schwer möglich. Eine eventuelle Aufbereitung implementierst du einmalig in der Exception-Klasse. Ich verstehe nicht was daran aufwendig ist. Außerdem habe ich lieber ein bisschen mehr Aufwand und verbringe dadurch nicht so viel Zeit mit der Fehlersuche, denn die dauert erfahrungsgemäß deutlich länger als ein bisschen Code reinzuhacken (das ist doch eh der geringste Teil am Programmieren).

Wie schon gesagt sind Formatierung und Sprache nicht entscheidend, sondern die enthaltenen Informationen. Bestimmte Dinge benötigen aber eine gewisse Lesbarkeit. Wenn ich eine Zeilennummer einfach nur als Zahl ausgebe, dann kann das sonstwas sein. Da wäre es schon schön wenn da noch sowas wie "line number" davor steht. ;) Und Beschreibungen in Exceptions sind völlig unabhängig vom Ausgabeziel. Ob das nun die Benutzeroberfläche, eine Log-Datei oder eine direkte Mail an den Entwickler ist, ist doch völlig unabhängig davon.
Ohne Input kein Output.
Antworten