Wie kann ich Aufrufe von assert () vollständig deaktivieren?


74

Mein Code ist voll von Anrufen an assert(condition). In der Debug-Version verwende ich, g++ -gdie meine Behauptungen auslöst. Unerwarteterweise werden dieselben Behauptungen auch in meiner Release-Version ausgelöst, die ohne -gOption kompiliert wurde .

Wie kann ich meine Zusicherungen beim Kompilieren vollständig deaktivieren? Sollte ich NDEBUGin jedem Build, den ich produziere, explizit definieren , unabhängig davon, ob es sich um Debug, Release oder etwas anderes handelt?


1
Etwas abseits des Themas: Wenn Sie Debug-Informationen wünschen, -gentspricht dies -g2. -g3könnte eine bessere Wahl sein, da es die symbolischsten Informationen zur Verfügung stellt. Beispielsweise sind unter -g3symbolische #defines verfügbar. Ich habe jedoch den Eindruck, dass einige Werkzeugketten ersticken -g3. Viele externe Bibliotheken hängen auch von -DDEBUG'Debug'-Builds ab (Posix bestätigt dies nur -DNDEBUGfür' Release'-Builds).
JWW

Antworten:


94

Sie müssen #define NDEBUG(oder das Flag -DNDEBUGmit g ++ verwenden ), dies wird Assert deaktivieren, solange es vor dem Einfügen der Assert-Header-Datei definiert ist.


1
muss vorher sein #include <assert.h>?
Lei Yang

2
@LeiYang Scheint, muss vor dem letzten hinzugefügt werden #include <assert.h>.
Eric Wang

35

Verwenden #define NDEBUG

7.2 Diagnose

1 Der Header definiert das Assert- Makro und verweist auf ein anderes Makro.

NDEBUG

was nicht definiert ist durch <assert.h>. Wenn NDEBUG de fi als Makroname an der Stelle in der Quelle definiert ist fi le , wo enthalten ist, die Assertion ist Makro de fi niert als einfach

#define assert(ignore) ((void)0)

Das Assert- Makro wird jedes Mal, wenn es enthalten ist, entsprechend dem aktuellen Status von NDEBUG neu definiert<assert.h> .


1
Hallo! Wenn es wahr ist, dass bei der Definition von -DNDEBUG immer noch ein Aufruf zum Bestätigen etwas ausführt, dh ((void) 0), wird dies minimale CPU-Zyklen kosten? Ich dachte, das wäre einfach auf nichts abgebildet, dh völlig KEIN CODE. Ist das nicht so?
Abruzzen Forte e Gentile

@Abruzzo: Ich dachte auch so , bis jetzt, aber es einen zweiten Gedanken, würde dies eine leeren lassen , ;anstatt, was problematisch sein kann , wenn die im assertInnern eine ist if, zum Beispiel. Ich bin sicher, dass der Compiler Zeilen wie 0;weg optimiert
Davka

@Abruzzo und BTW prüfen, ob Sie mit Ihrer IDE oder Ihrem Build-System eine Standardvorlage für ein neues Projekt angeben können. Dann können Sie NDEBUG in der Release-Konfiguration jedes neuen Projekts definieren lassen
davka

@Abruzzo Was meinst du mit keinem Code? In der ausführbaren Datei wird kein Code von ((void) 0) generiert. Und der Standard verlangt, dass assert überall dort verwendet werden kann, wo ein Ausdruck mit void-Typ verwendet werden kann. Ersetzen Sie ihn also einfach ohne Token, was auch immer nicht funktioniert.
James Kanze

Der Compiler optimiert es zur Kompilierungszeit. Betrachten Sie es als NOP. Nutzlose NOPs werden entfernt, dies ist jedoch vom Compiler abhängig. Wenn Sie beispielsweise MIPS-Code kompilieren, können Assembly-Dateien vorhanden sein, in denen NOPs verbleiben, um den Zweig abzudecken und Verzögerungen zu laden, an denen Anweisungen ausgerichtet werden müssen, um zyklische Grenzen oder undefiniertes Verhalten zu takten.
user2262111

11

Sie können Assertions entweder vollständig deaktivieren, indem Sie

#define NDEBUG
#include <assert.h>

oder Sie können NDEBUG (über -DNDEBUG) in Ihrer Makefile- / Build-Prozedur festlegen, je nachdem, ob Sie eine produktive oder eine Entwicklungsversion wünschen.


10

Das -gFlag hat keinen Einfluss auf den Betrieb von assert, sondern stellt lediglich sicher, dass verschiedene Debugging-Symbole verfügbar sind.

Rahmen NDEBUG ist die Standardmethode (wie im offiziellen ISO-Standard) zum Deaktivieren von Zusicherungen.


4

Ja, definieren Sie NDEBUGin der Befehlszeile / im Build-System mit der Option Präprozessor / Compiler-DNDEBUG .

Dies hat nichts mit den von eingefügten Debugging-Informationen zu tun -g.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.