Sauberer Code`?
-
Original erstellt von japro:
hmm komm ^jetzt nicht ganz draus. ist das ein beispiel was due unter abfangen von fehlercodes verstehst (new wirft eine exeption gell). oder wenn du oft sowas siehst isses schlecht.im VC++6 wirft new keine exception also ist es in ordnung den return value von new abzufragen - aber wer kann mir sagen warum man dafür NIE NIE NIE assert verwenden darf??
-
Original erstellt von Shade Of Mine:
aber wer kann mir sagen warum man dafür NIE NIE NIE assert verwenden darf??weil du bist ein programmierer, jemand mit 512 MB Ram aber dein kunde der die release version bekommt ein office user ist mit 64 MB Ram
aber auf den meisten os ist es so wieso sinnlos auf speicher knapheit zu prüfen, die aktuellen oses geben dir bist zu 2 GB (nur das der rechner unbenutzbar wird und in die knie geht)
problem sind die user die ihre swap datei ausmachen
-
@Dimah:
assert ist für Logikfehler!
und ein out of memory ist kein logikfehler...sinn hat es insofern diese sachen abzufangen, dass du dem user dann sagen kannst: "Programm wurde wegen Speicherknappheit beendet - bitte kontaktieren sie den Support" - dagegen wenn du die sachen nicht abfängst stürtt die anwendung dann einfach ab.
zB wenn die swap dateien vergrößert werden dann kann es sein dass win2k speicher abfragen ablehnt - ich denke es hat durchaus sinn diese fehler abzufangen - denn am ende hast du dann den kunden der sagt: das programm ist abgesuertzt und du hast 0 ahnung warum...
-
assert ist für Logikfehler!
ist mir aber ganz neu
-
Original erstellt von Shade Of Mine:
**assert ist für Logikfehler!
**ich muß dich leider davon in kenntnis setzen, daß das nicht mehr der fall ist.
für logigfehler verwendet man (char)0=0;. das ruft auch keine destruktoren von auto-objekten auf aber erschrickt wenigstens den user angemessen, damit er weiß, welches programm die filelocks offen gelassen hat und seine temp-files nicht löscht und die gestarteten abhängigen prozesse nicht killt und so.
ich kenne einen, der hat beim arbeiten an einer dynamischen hashtable mehrmal seinen rechner neu booten müssen, weil er auf diese weise gelockte files gelockt ließ.menes erachtens nach muß man sich ein eigenes ASSERT bauen, das, wenn das prog nen debugger dahinter hat, den anwirft, und egal ob debugger dahinter oder nicht, ne exception wirft, in der mindestens dateiname und zeilennummer stehen. die main fängt sowas spätestens mit ihrem catch(...).
-
Original erstellt von volkard:
menes erachtens nach muß man sich ein eigenes ASSERT bauenstimmt, aber mit assert() meinte ich nicht unbedingt das assert der Standard Library sondern generell den Mechanismus eines asserts (im gegensatz zum werfen von exceptions)
-
menes erachtens nach muß man sich ein eigenes ASSERT bauen, das, wenn das prog nen debugger dahinter hat, den anwirft, und egal ob debugger dahinter oder nicht, ne exception wirft, in der mindestens dateiname und zeilennummer stehen. die main fängt sowas spätestens mit ihrem catch(...).
http://www.cuj.com/experts/2104/alexandr.htm
Mit kleinen Anpassungen läuft der Code auch auf dem VC 6.
[ Dieser Beitrag wurde am 13.05.2003 um 19:13 Uhr von HumeSikkins editiert. ]
-
für logigfehler verwendet man (char)0=0;
Wer definiert was 'man' macht? Ich habe davon bis eben noch nie was gehört. Lese also wohl die falschen Bücher/Artikel/Newsgroups.
-
hier was, das ich mal gebaut habe:
//debug.h inline doNothing(){} #define MIF(when,what) if(when){what;}else doNothing() #ifndef NDEBUG #define DBREAK() MIF(IsDebuggerPresent(),__asm{int 3}) #else #define DBREAK() doNothing() #endif #define THROW(exception) MIF(true,throw exception) #define DTHROW(exception) MIF(true,DBREAK();throw exception) #ifndef NDEBUG #define IFDEBUG(x) x #else #define IFDEBUG(x) #endif #ifndef NDEBUG #define ASSERT(assertion) MIF(!(assertion),DTHROW(AssertException(THISLINE()))) #else #define ASSERT(assertion) __assume(assertion) #endif
[ Dieser Beitrag wurde am 13.05.2003 um 19:48 Uhr von volkard editiert. ]
-
wieso nicht statt
#define THROW(exception) MIF(true,throw exception) #define DTHROW(exception) MIF(true,DBREAK();throw exception)
einfach
#define THROW(exception) throw exception #define DTHROW(exception) DBREAK();throw exception
oder übersehe ich hier was?
-
Original erstellt von Dimah:
**wieso nicht statt#define THROW(exception) MIF(true,throw exception) #define DTHROW(exception) MIF(true,DBREAK();throw exception)
einfach
#define THROW(exception) throw exception #define DTHROW(exception) DBREAK();throw exception
oder übersehe ich hier was?**
if(bla()) DTHROW("klappt nicht"); else blubb();
also DTHROW brächte mindestens noch nen block um sich.
das MIF hat sein if mit nem else versehen, damits da keinen ärger geben kann. aber sicher sind andere implementierungen möglich.
-
Original erstellt von Shade Of Mine:
im VC++6 wirft new keine exception also ist es in ordnung den return value von new abzufragenund auf meinem kompiler kann ich mit new die quadratwurzeln berechnen also ist das ok wenn ich das mache...
-
Original erstellt von japro:
**
und auf meinem kompiler kann ich mit new die quadratwurzeln berechnen also ist das ok wenn ich das mache...**ne, mal im ernst - wenn du weißt dass dein compiler bei new KEINE exception wirft, was machst du dann?
dir sagen: ach was solls, dann ignoriere ich das halt?
jo, dann mach das, zwingt dich ja keiner deinen code auf fehler zu prüfen.
aber was ist daran falsch? NICHTS! es ist NICHT UNDEFINIERT den return wert von new abzufragen.
und manche leute denken sich halt, dass man diese 1 if in kauf nehmen kann (um dann uU selber bad_alloc zu werfen). stört es dich?
schau dir mal boost an, oder GNU libraries - da geht es darum dass der code überall läuft, um das zu erreichen nimmt man gewisse sachen in kauf - und ein mikriges if ist es wirklich nicht wert, dass das fertige programm dann nicht mit vc++6 laufen wird.
aber bitte - ich wette du brauchst keine portablen programme - das läuft sicher alles bei dir schön und gut und wehe jemand kommt auf die idee den code auch nur n bisschen portabel zu machen...
was stört dich an
p=new T;
if(!p) throw bad_alloc();
ist das böse? ist es undefiniert? was ist es?
es ist garnix!
wenn wir das in ein define stecken, dann ist es auf anderen compilern nichtmal mehr da.aber es gibt halt leute die denken sich, ich will nicht portieren, ich will dass es nur bei mir läuft - schön und gut. und wenn sie den VC++ 6 verwenden, was sollen sie dann machen? generell die out of memory situation ignorieren?
was würdest du machen?
ha, sags nicht: nen anderen compiler nehmen, stimmts?
-
Original erstellt von Shade Of Mine:
was würdest du machen?
ha, sags nicht: nen anderen compiler nehmen, stimmts?"effektiv c++" lesen und mit set_new_handler eine funktion setzen die std::bad_alloc wirft
-
set_new_handler ist möglich, aber dann gibt es immer noch die situation wenn exception handling deaktiviert ist (zB aus performance gründen) - es geht mir nur darum, dass nix falsch daran beim vc++ new auf 0 zu checken...
es anders machen kann man fast immer - aber es ist weder undefiniert noch implementation definied noch sonstwas. es ist legaler c++ code!
-
Original erstellt von Shade Of Mine:
set_new_handler ist möglich, aber dann gibt es immer noch die situation wenn exception handling deaktiviert ist (zB aus performance gründen)Normalerweise wegen der Programmgröße. Für Exceptions muss der Compiler so ziemlich an jeder mögliche Stelle unwind-Code einfügen, so dass sich die Größe sich von Binaries signifikant erhöht.
ist das böse? ist es undefiniert? was ist es?
Re
dun
dan
t vielleicht? Auf die Idee, dass man überflüssige Dinge nicht (in den Quelltext) schreibt, weil es die Lesbarkeit vermindert, bist Du noch nicht gekommen?