2009-09-19 4 views
1

Certaines assertions sont coûteuses, d'autres sont mieux désactivées au code de production. Au moins, il n'est pas clair que les assertions doivent toujours être activées.Stratégies pratiques pour les vérifications d'assertions

Dans mon application, je voudrais être en mesure d'activer/désactiver une partie des assertions par fichier ou par classe.

Comment le faire en C++?

+0

Activation/désactivation au moment de la compilation ou de l'exécution? –

+0

Bon point. Au moment de la compilation. –

Répondre

2

Pour désactiver le module à l'échelle affirme j'utiliser:

#if defined(assert) 
# undef assert 
# define assert(x) ((void)0) 
#endif 

... Bien sûr, cela peut être simplifiée si vous êtes d'accord avec l'aide d'une macro personnalisée.

#if defined(_NO_ASSERTS) 
# define myAssert(x) ((void)0) 
#else 
# define myAssert(x) assert(x) 
#endif 

Pour désactiver la classe à l'échelle j'utiliser un membre statique de classe const ou en combinaison ENUM de classe à l'échelle avec une macro personnalisée:

#define myAssert(x) do { if(_CLASS_ASSERT) { assert(x); } } while(0) 

class AssertOff 
{ 
    enum { _CLASS_ASSERT = 0 } 
} 

Avec énumérations et const bools statiques tous les compilateurs modernes devrait optimiser loin le if(_CLASS_ASSERT) {}.

+0

Bonne idée avec l'énumération. Merci. –

0

Pour désactiver les assertions d'un fichier C++, vous pouvez faire une des opérations suivantes:

  • Définir la constante NDEBUG près du sommet du fichier source. Ajoutez les -DNDEBUG aux options de compilation du fichier source.

La plupart des EDI et/ou l'infrastructure de construction vous permettent de spécifier des options de génération par fichier, c'est donc une solution facile.

La désactivation des assertions par classe est plus difficile lorsque plusieurs classes sont mélangées dans le même fichier source ou que vous avez beaucoup de fonctions intégrées dans vos fichiers d'en-tête. Vous pouvez bien sûr #define NDEBUG et #undef NDEBUG dans les endroits appropriés.

Étant donné que certains IDE s'attendent à pouvoir définir NDEBUG pour les générations non-debug, vous pouvez le rendre plus extensible en choisissant votre propre nom de macro, tel que DISABLE_ASSERT. Ensuite, inclure le code comme comme le suivant dans un fichier d'en-tête commune (qui n'est pas précompilées):

#ifdef DISABLE_ASSERT 
#define NDEBUG 
#endif 
+1

'#define NDEBUG' peut avoir d'autres effets secondaires indésirables en plus de désactiver les assertions. –

+0

Quels sont les effets secondaires? –

+0

désactivant d'autres macros/code de débogage et non seulement les affirme. –

1

Coder avec des affirmations considère un bon style de codage.

Comme pour l'exécution Activation/Désactivation Vous pouvez le faire avec une variable booléenne. Par exemple dans votre code, vous pouvez effectuer les opérations suivantes:

Définir une variable qui sera utilisée pour indiquer si les assertions sont activées ou désactivées dans un espace de noms global (par exemple, hors de votre fonction main() dans le même fichier) .

bool turnOnAssertions; 

Définir une variable comme écrit ci-dessous dans d'autres fichiers où vous voulez activer/désactiver vos affirmations:

extern bool turnOnAssertions; 

Donc, en manipulant la variable turnOnAssertions avec l'interface utilisateur et de l'écriture

if(turnOnAssertions) 
assert(…); 

vous pouvez activer/désactiver certaines de vos assertions!

En ce qui concerne le temps de compilation vous devez faire ce qui suit:

Pour vous compilateur vous devez donner un drapeau comme -DASSERTIONSON (-Dflag_name [nom du drapeau que vous pouvez définir tout ce que vous voulez])

#ifdef ASSERTIONSON 
bool turnOnAssertions = true; 
#else 
bool turnOnAssertions = false; 
#endif 

Et utilisez simplement la variable.

Bonne chance!

Questions connexes