Strategie utili per la verifica delle asserzioni
-
11-09-2019 - |
Domanda
Alcune asserzioni sono costose, altre è meglio disattivarle nel codice di produzione.Almeno non è chiaro se le asserzioni dovrebbero essere sempre abilitate.
Nella mia applicazione vorrei essere in grado di attivare/disattivare parte delle asserzioni in base al file o alla classe.
Come farlo in C++?
Soluzione
per la disattivazione afferma modulo a livello userei:
#if defined(assert)
# undef assert
# define assert(x) ((void)0)
#endif
... naturalmente questo può essere semplificato se si sta bene con l'utilizzo di una macro personalizzata.
#if defined(_NO_ASSERTS)
# define myAssert(x) ((void)0)
#else
# define myAssert(x) assert(x)
#endif
Per la classe a livello di disattivazione userei un membro della classe static const o un enum a livello di classe, in combinazione con una macro personalizzata:
#define myAssert(x) do { if(_CLASS_ASSERT) { assert(x); } } while(0)
class AssertOff
{
enum { _CLASS_ASSERT = 0 }
}
Con le enumerazioni e Caccio static const tutti i compilatori moderni dovrebbero ottimizzare via il if(_CLASS_ASSERT) {}
.
Altri suggerimenti
Codificare con asserzioni considera un buon stile di codifica.
Per quanto riguarda l'autonomia accensione/spegnimento Puoi farlo con la variabile booleana.Ad esempio nel tuo codice puoi fare quanto segue:
Definisci una variabile che verrà utilizzata per indicare se le asserzioni sono attivate o disattivate in uno spazio dei nomi globale (ad esempio dalla funzione main() nello stesso file).
bool turnOnAssertions;
Definisci una variabile come scritto di seguito in altri file in cui desideri attivare/disattivare le tue asserzioni:
extern bool turnOnAssertions;
Quindi manipolando la variabile turnOnAssertions con l'interfaccia utente e scrivendo
if(turnOnAssertions)
assert(…);
puoi attivare/disattivare alcune delle tue asserzioni!
Per quanto riguarda il tempo di compilazione dovresti fare quanto segue:
Per il tuo compilatore dovresti fornire un flag come –DASSERTIONSON (-Dflag_name [nome flag che puoi impostare come preferisci])
#ifdef ASSERTIONSON
bool turnOnAssertions = true;
#else
bool turnOnAssertions = false;
#endif
E usa semplicemente la variabile.
Buona fortuna!
Per disabilitare le asserzioni di un file C ++, si potrebbe fare una delle seguenti:
- Definisci la costante
NDEBUG
vicino alla parte superiore del file di origine. - Aggiungi il
-DNDEBUG
alle opzioni di compilazione per il file di origine.
La maggior parte dei IDE e / o costruire infrastrutture consentono di specificare costruire opzioni per file, quindi questa è una soluzione facile.
La disattivazione affermazioni su una base per classe è più difficile quando più le classi sono mescolati nello stesso file di origine o si hanno un sacco di funzioni inline nei file di intestazione. Ovviamente si può #define NDEBUG
e #undef NDEBUG
nella sezione corrispondente.
Dal momento che alcuni IDE si aspettano di essere in grado di impostare NDEBUG
per i non-build di debug, si potrebbe rendere più estensibile, scegliendo il proprio nome di macro, come ad esempio DISABLE_ASSERT
. Quindi includere codice come simile al seguente in un file di intestazione comune (che non è precompilato):
#ifdef DISABLE_ASSERT
#define NDEBUG
#endif