Antworten:
Visual Studio definiert, _DEBUG
wann Sie die Option /MTd
oder angeben /MDd
, und NDEBUG
deaktiviert Standard-C-Zusicherungen. Verwenden Sie sie gegebenenfalls, dh _DEBUG
wenn Sie möchten, dass Ihr Debugging-Code mit den MS CRT-Debugging-Techniken übereinstimmt , und NDEBUG
wenn Sie mit diesen übereinstimmen möchten assert()
.
Wenn Sie Ihre eigenen Debugging-Makros definieren (und den Compiler oder die C-Laufzeit nicht hacken), vermeiden Sie es, Namen mit einem Unterstrich zu beginnen, da diese reserviert sind.
Ist NDEBUG Standard?
Ja, es ist ein Standardmakro mit der semantischen Bezeichnung "Nicht debuggen" für die Standards C89, C99, C ++ 98, C ++ 2003, C ++ 2011, C ++ 2014. _DEBUG
Die Standards enthalten keine Makros.
C ++ 2003 Standard Senden Sie den Reader auf "Seite 326" unter "17.4.2.1 Header" an Standard C.
Dieser NDEBUG ist ähnlich wie Dies ist derselbe wie die Standard C-Bibliothek.
In C89 (C-Programmierer nannten diesen Standard als Standard C) wurde im Abschnitt "4.2 DIAGNOSE" gesagt
http://port70.net/~nsz/c/c89/c89-draft.html
Wenn NDEBUG an der Stelle in der Quelldatei, an der es enthalten ist, als Makroname definiert ist, wird das Assert-Makro einfach als definiert
#define assert(ignore) ((void)0)
Wenn Sie sich die Bedeutung von _DEBUG
Makros in Visual Studio
https://msdn.microsoft.com/en-us/library/b0084kay.aspx ansehen
, wird ersichtlich, dass dieses Makro automatisch durch Ihre Wahl der Version der Sprachlaufzeitbibliothek definiert wird.
Ich verlasse mich darauf NDEBUG
, weil es das einzige ist, dessen Verhalten über Compiler und Implementierungen hinweg standardisiert ist (siehe Dokumentation für das Standard-Assert-Makro). Die negative Logik ist ein kleiner Speedbump für die Lesbarkeit, aber es ist eine gängige Redewendung, an die Sie sich schnell anpassen können.
Sich auf so etwas zu verlassen, _DEBUG
würde bedeuten, sich auf ein Implementierungsdetail eines bestimmten Compilers und einer bestimmten Bibliotheksimplementierung zu verlassen. Andere Compiler können dieselbe Konvention wählen oder nicht.
Die dritte Möglichkeit besteht darin, ein eigenes Makro für Ihr Projekt zu definieren, was durchaus sinnvoll ist. Mit Ihrem eigenen Makro können Sie Implementierungen über Implementierungen hinweg durchführen und Ihren Debugging-Code unabhängig von den Zusicherungen aktivieren oder deaktivieren. Im Allgemeinen rate ich jedoch davon ab, verschiedene Klassen von Debugging-Informationen zu haben, die zur Kompilierungszeit aktiviert werden, da dies zu einer Zunahme der Anzahl von Konfigurationen führt, die Sie erstellen (und testen) müssen, um einen wohl geringen Nutzen zu erzielen.
Wenn Sie bei einer dieser Optionen Code von Drittanbietern als Teil Ihres Projekts verwenden, müssen Sie wissen, welche Konvention verwendet wird.
#if !defined(NDEBUG)
<- @HostileFork hast du das nicht gemeint? #if
nicht #ifdef
?
#ifdef NDEBUG
... aber dann besondere Aufmerksamkeit auf die negative Logik mit gelenkt wird #if !defined(NDEBUG)
. Ansonsten ist es ein wenig schwierig, das n in #ifndef NDEBUG
"
Das Makro NDEBUG
steuert, ob assert()
Anweisungen aktiv sind oder nicht.
Meiner Ansicht nach unterscheidet sich das von jedem anderen Debugging. Daher verwende ich etwas anderes als NDEBUG
die Steuerung der Debugging-Informationen im Programm. Was ich benutze, hängt vom Framework ab, mit dem ich arbeite. Verschiedene Systeme haben unterschiedliche Aktivierungsmakros, und ich verwende alles, was angemessen ist.
Wenn es kein Framework gibt, würde ich einen Namen ohne führenden Unterstrich verwenden. Diese sind in der Regel der Implementierung vorbehalten, und ich versuche, Probleme mit Namenskollisionen zu vermeiden - doppelt so, wenn der Name ein Makro ist.
#if
Einfügen von Behauptungen in eine Kategorie und von kontrolliertem Code in die andere. assert(huge_object.IsValid());
könnte langsam sein, während es assert(ptr != nullptr);
wahrscheinlich nicht ist. Ich stimme Jonathan zu, dass sich Protokollierung und Ablaufverfolgung wahrscheinlich von Behauptungen unterscheiden sollten, zumindest in größeren Projekten, aber ich denke nicht an Protokollierung oder Ablaufverfolgung als Debug-Code, weshalb ich um Klarstellung gebeten habe.
Ist leider DEBUG
stark überlastet. Beispielsweise wird empfohlen, immer eine PDF-Datei für RELEASE-Builds zu generieren und zu speichern. Was bedeutet, eines der -Zx
Flags und -DEBUG
Linker-Option. While _DEBUG
bezieht sich auf spezielle Debug-Versionen der Laufzeitbibliothek, z. B. Aufrufe von malloc
und free
. Dann NDEBUG
werden Zusicherungen deaktiviert.