Risposte:
Visual Studio definisce _DEBUG
quando si specifica l' opzione /MTd
o /MDd
, NDEBUG
disabilita le asserzioni C standard. Usali quando appropriato, ad esempio _DEBUG
se vuoi che il tuo codice di debug sia coerente con le tecniche di debug di MS CRT e NDEBUG
se vuoi essere coerente assert()
.
Se si definiscono le proprie macro di debug (e non si compromette il compilatore o il runtime C), evitare di iniziare i nomi con un trattino basso, poiché sono riservati.
NDEBUG è standard?
Sì, è una macro standard con il semantico "Not Debug" per gli standard C89, C99, C ++ 98, C ++ 2003, C ++ 2011, C ++ 2014. Non ci sono _DEBUG
macro negli standard.
Lo standard C ++ 2003 invia il lettore a "pagina 326" a "17.4.2.1 Intestazioni" allo standard C.
Che NDEBUG è simile a Questo è lo stesso della libreria C standard.
In C89 (i programmatori C hanno definito questo standard come standard C) nella sezione "4.2 DIAGNOSTICA" è stato detto
http://port70.net/~nsz/c/c89/c89-draft.html
Se NDEBUG è definito come un nome di macro nel punto nel file di origine in cui è incluso, la macro di asserzione viene definita semplicemente come
#define assert(ignore) ((void)0)
Se si guarda al significato delle _DEBUG
macro in Visual Studio
https://msdn.microsoft.com/en-us/library/b0084kay.aspx
, si vedrà che questa macro viene definita automaticamente dalla tua versione della libreria di runtime della lingua.
Mi affido NDEBUG
, perché è l'unico il cui comportamento è standardizzato tra compilatori e implementazioni (vedere la documentazione per la macro assert standard). La logica negativa è un piccolo speedbump di leggibilità, ma è un linguaggio comune a cui puoi rapidamente adattarti.
Fare affidamento su qualcosa del genere _DEBUG
significherebbe fare affidamento su un dettaglio di implementazione di un particolare compilatore e implementazione della libreria. Altri compilatori possono o meno scegliere la stessa convenzione.
La terza opzione è definire la tua macro per il tuo progetto, il che è abbastanza ragionevole. Avere la propria macro offre la portabilità tra le implementazioni e consente di abilitare o disabilitare il codice di debug indipendentemente dalle asserzioni. Tuttavia, in generale, sconsiglio di avere diverse classi di informazioni di debug che sono abilitate in fase di compilazione, poiché provoca un aumento del numero di configurazioni che devi costruire (e testare) per un vantaggio discutibilmente piccolo.
Con una di queste opzioni, se usi codice di terze parti come parte del tuo progetto, dovrai essere consapevole di quale convenzione utilizza.
#if !defined(NDEBUG)
<- @HostileFork non è quello che volevi dire? #if
no #ifdef
?
#ifdef NDEBUG
... ma quindi chiamare una particolare attenzione alla logica negativa con #if !defined(NDEBUG)
. Altrimenti è un po 'difficile trovare la n #ifndef NDEBUG
"
La macro NDEBUG
controlla se le assert()
istruzioni sono attive o meno.
A mio avviso, questo è separato da qualsiasi altro debug, quindi uso qualcosa di diverso da NDEBUG
controllo delle informazioni di debug nel programma. Quello che uso varia a seconda del framework con cui sto lavorando; sistemi diversi hanno macro abilitanti diverse e utilizzo tutto ciò che è appropriato.
Se non esiste un framework, utilizzerei un nome senza un trattino basso iniziale; quelli tendono ad essere riservati all '"implementazione" e cerco di evitare problemi con le collisioni di nomi - doppiamente quando il nome è una macro.
#if
codice controllato nell'altra. assert(huge_object.IsValid());
potrebbe essere lento mentre assert(ptr != nullptr);
probabilmente non lo è. Concordo con Jonathan sul fatto che la registrazione e la traccia dovrebbero probabilmente essere distinte dalle asserzioni, almeno in progetti più grandi, ma non penso alla registrazione o alla traccia come codice di debug, motivo per cui ho chiesto chiarimenti.
Purtroppo DEBUG
è sovraccarico pesantemente. Ad esempio, si consiglia di generare e salvare sempre un file pdb per build RELEASE. Il che significa una delle -Zx
bandiere e l' -DEBUG
opzione linker. Mentre si _DEBUG
riferisce a versioni speciali di debug della libreria di runtime come le chiamate a malloc
e free
. Quindi NDEBUG
disabiliterà le asserzioni.