2014-12-03 8 views
5

Ich habe gegraben nur einen Fehler in einigen Code bis wir mit * arbeiten, die aufgrund der folgenden Situation versagte:Funktionsaufruf innerhalb der Assert == schlecht?

Assert(SomeVitalFunction(foo) == OK) 

Diese Zeit alle DEBUG Makros funktionierte gut #defined wurden:

#ifdef DEBUG 
    #define Assert(x) if((x) == 0){/*some error handling*/} 
#else 
    #define Assert(x) 
#endif 

Aber wenn wir #undef'd DEBUG es hat die Wirkung der Vitalfunktion Anruf aus dem Code zu löschen.

Ich kann nicht für das Leben von mir erarbeiten, wie das jemals mit DEBUG #undef 'd funktionieren könnte, und es scheint eine schlechte Idee im Allgemeinen jede Art von Funktionsaufruf innerhalb einer Assert wie folgt zu setzen.

Habe ich etwas verpasst?

* = bearbeiten folgende Carpetsmoker Kommentar zu klären: Der Code stammt aus einem besonders rückwärts Kabale Elbonian Code Sklaven hat unsere Aufgabe zu hacken gewesen, hieb, rasiert, Politur, sanieren und Lippenstift auf die Sache an.

+3

Der Sinn von 'assert' ist es" * Programmierern zu helfen, Fehler in ihren Programmen zu finden * "... Also sollten alle Anwendungen idealerweise entfernbar sein, und alles sollte immer noch gleich funktionieren. Sie haben also Recht bei Ihrer Beobachtung, und Sie oder einer Ihrer Mitarbeiter haben in der Vergangenheit einen Fehler gemacht. – Carpetsmoker

+0

Ich habe vor langer Zeit ein Visual Studio-Makro geschrieben, um durch die Codebasis zu schauen (damals suchte ich nach ASSERT (... (...) '- also 2 oder mehr öffnende Klammern vor dem schließenden), weil es so ist so ein großes Problem, wenn es passiert. – AAT

Antwort

5

Sie haben nichts verpasst.

Asserts sollten immer so geschrieben werden, als könnten sie mit einem Compilerwechsel verschwinden.

Sie können Funktionen aufrufen, die eine relativ lange Zeit benötigen, um eine Assert (zum Beispiel die Integrität einer Datenstruktur) zu vervollständigen, weil der Funktionsaufruf in der Versionserstellung nicht vorhanden sein wird. Die Kehrseite davon ist, dass Sie nicht Funktionen aufrufen können, die für den korrekten Betrieb erforderlich sind.

2

Es hängt davon ab, was SomeVitalFunction tut. Wenn es keine interessante Nebenwirkungen hat, ist es in Ordnung, es in einem assert zu verwenden. Aber wenn das Programm SomeVitalFunction anruft oder nicht, ist es ein Fehler.

Zum Beispiel, auf POSIX, kill(2) mit einem 0-Signal ist nur nützlich, um zu testen, ob ein Prozess lebt. Ich könnte mir vorstellen, dass Sie vielleicht manchmal

assert(kill(sompid, 0) == 0); // process sompid exists 

davon aus, dass man immer annehmen zu verwenden versucht sein, dass der Prozess sompid noch läuft.

Sie könnten auch assert(hash_table_count(htbl)>0); verwenden, um zu überprüfen, dass einige Hash-Tabelle htbl nicht leer ist.

BTW, feststellen, dass assert(3)dokumentiert ist als ignoriert zu werden, wenn Sie mit -DNDEBUG Präprozessor Option kompilieren (nicht wenn -DDEBUG nicht gegeben ist).