assert() vs std::invalid_argument
-
314159265358979 schrieb:
Hacker schrieb:
Zwei Sachen versteh ich an PI's Idee nicht.
#define TO_STRING_I(x) #x #define TO_STRING(x) TO_STRING_I(x)Wieso nicht gleich
#define TO_STRING(x) #xProbiers aus.

Hab ich.

-
Dann wirst du doch den Unterschied sehen, oder?

-
314159265358979 schrieb:
Dann wirst du doch den Unterschied sehen, oder?

N-Ö?
#define TO_STRING_I(x) #x #define TO_STRING(x) TO_STRING_I(x) int main() { std::cout << string() + TO_STRING_I(5) << '\n' << string() + TO_STRING(6) << '\n'; }
-
Dann probiers mal mit __LINE__.

-
otze schrieb:
Ich habe früher assert benutzt, bis ich irgendwann raus gefunden hab, dass das total unkonfortabel ist. assert bringt dir nur etwas, wenn der Debugger an ist. Eine schöne Exception kann dir direkt Fehlermeldung + Position im Code mit raus geben.
Assertions benutzt man ja auch nur um Programmierfehler abzufangen.
assert(ptr != nullptr)Gibt mir die Information darüber dass hier ein Pointer null ist und auch die Position im Code. Die Exception bringt hier keine Vorteile, ohne Macros aber Runtime-Overhead.
-
Ethon__ schrieb:
Gibt mir die Information darüber dass hier ein Pointer null ist und auch die Position im Code. Die Exception bringt hier keine Vorteile, ohne Macros aber Runtime-Overhead.
Natürlich sollte sich ein assert Ersatz der auf Expcetions basiert, sich genauso verhalten wie assert: im Release kein Overhead. Warum bist du jetzt schon der Dritte mit dieser Anmerkung?
So siehts aus:
#define EXCEPTION(message) Exception(message, __FILE__, __LINE__) #ifndef NDEBUG #define SIZE_CHECK(cond) do { if (!(cond)) throw EXCEPTION("size mismatch:"#cond); } while (false) #else #define SIZE_CHECK(cond) do { (void)sizeof(cond); } while (false) #endif //Benutzung: SIZE_CHECK(vector1.size()==vector2.size());
-
IMO sollte man das Semikolon ins Makro reinziehen, da Makro selbst weiß, dass eines benötigt wird. Für den Benutzer des Makros ist das oft nicht sofort ersichtlich. Meine Faustregel: Alle Makros so gestalten, dass keine abschließenden Semikola benötigt werden. Wozu du hier do-while verwendest, verstehe ich nicht.
-
314159265358979 schrieb:
Wozu du hier do-while verwendest, verstehe ich nicht.
Um ein Semikolon hinter den Aufruf setzen zu können:
#define SET_TO_NULL(x) { x = 0; cout << "SET_TO_NULL" << endl; } #define SET_TO_NULL2(x) do { x = 0; cout << "SET_TO_NULL2" << endl; } while(false) int main() { int x = 4; if(x != 0) SET_TO_NULL(x); else // Fehler: else ohne if cout << "Nichts zu tun hier" << endl; x = 4; if(x != 0) SET_TO_NULL2(x); else cout << "Nichts zu tun hier" << endl; }Ich finde ein Semikolon hinterm Aufruf schöner, weil es so konform zu allen anderen Ausdrücken ist.
-

Naja, ich finde es doof, dass man bei manchen Makros ein setzen muss und bei anderen nicht. Daher mach ichs so, dass man nie eines setzen muss.
-
Und ich finde es doof, wenn Makros sich anders verhalten als Funktionsaufrufe.
Da ist die do-while Technik ideal, denn die funktioniert überall wie ein Funktionsaufruf, auch in {}-losen Schleifen oder sogar verschachtelten if's.z.T. ASSERT(): man kann ja auch nen Dump schreiben und den Prozess dann abbrechen. Dann hat man nicht nur Sourcefile/Zeilennummer, sondern gleich die Callstacks von allen Threads, und je nach Einstellungen sogar den gesamten Speicherinhalt.
-
hustbaer schrieb:
z.T. ASSERT(): man kann ja auch nen Dump schreiben und den Prozess dann abbrechen. Dann hat man nicht nur Sourcefile/Zeilennummer, sondern gleich die Callstacks von allen Threads, und je nach Einstellungen sogar den gesamten Speicherinhalt.
Wie würde das mit dem Callstack plattform/compilerunabhängig gehen? Interesse an erweitertern Fehlermeldungen habe ich immer.
-
otze schrieb:
hustbaer schrieb:
z.T. ASSERT(): man kann ja auch nen Dump schreiben und den Prozess dann abbrechen. Dann hat man nicht nur Sourcefile/Zeilennummer, sondern gleich die Callstacks von allen Threads, und je nach Einstellungen sogar den gesamten Speicherinhalt.
Wie würde das mit dem Callstack plattform/compilerunabhängig gehen? Interesse an erweitertern Fehlermeldungen habe ich immer.
Na gar nicht, es sei denn du findest eine Lib' die das für dich abstrahiert.
Musst du halt Code für jede Plattform schreiben.
Sollte aber auch kein Beinbruch sein.