web-dev-qa-db-fra.com

Dans quels cas faut-il inclure <cassert>?

Dans quels cas faut-il inclure cassert?

49
Jane

En bref, ne l'utilisez pas; utilisez <assert.h>.

C++ 11 a supprimé toute garantie formelle d'un en-tête "c ...." ne polluant pas l'espace de noms global.

Ce n'était jamais une garantie dans la pratique, et maintenant ce n'est même plus une garantie formelle.

Par conséquent, avec C++ 11, il n'y a plus d'avantage imaginable à utiliser les variantes d'en-tête "c ....", alors qu'il y a l'inconvénient clair et net que le code qui fonctionne bien avec un compilateur et une version de ce compilateur, peut échec de la compilation avec un autre compilateur ou une autre version, en raison, par exemple, collisions de noms ou sélection de surcharge différente dans l'espace de noms global.

SO, alors que cassert était assez vide de sens en C++ 03 (vous ne pouvez pas mettre une macro dans un espace de noms), il est totalement vide de sens - même en tant que cas spécial d'un schéma général - en C + +11.


Addendum , 22 décembre 2013:

La norme définit chaque en-tête C++ C <X.h> en termes d'en-tête <cX>, qui à son tour est défini en termes d'en-tête de bibliothèque C correspondant.

C++ 11 §D.5/2 :

"Chaque en-tête C, dont chacun a un nom de la forme name.h, Se comporte comme si chaque nom placé dans l'espace de noms de la bibliothèque standard par l'en-tête correspondant cname est placé dans la portée de l'espace de noms global. "

C++ 11 §D.5/3 (exemple non normatif):

"L'en-tête <cstdlib> Fournit assurément ses déclarations et définitions dans l'espace de noms std. Il peut également fournir ces noms dans l'espace de noms global. L'en-tête <stdlib.h> Fournit assurément les mêmes déclarations et définitions dans l'espace de noms global, un peu comme dans la norme C. Il peut également fournir ces noms dans l'espace de noms std. ”

L'utilisateur de Stack Overflow CR m'a fait prendre conscience que certaines versions de g ++, telles que MinGW g ++ 4.7.2, sont tout à fait non standard par rapport aux en-têtes <X.h>, sans les surcharges de sin que la norme C++ requiert:

Je savais déjà que MinGW g ++ 4.7.2 manquait également entièrement de fonctions telles que swprintf, et qu'il avait idem des défauts dans la bibliothèque C++ pure comme l'absence de C++ 11 std::to_string. Cependant, les informations à ce sujet sans les surcharges de la fonction C étaient nouvelles pour moi.

En pratique, les surcharges manquantes avec g ++ signifient

  • ignorer le problème g ++, ou

  • éviter d'utiliser les surcharges g ++ manquantes,
    par exemple. en utilisant uniquement double sin( double ), ou

  • en utilisant les surcharges de l'espace de noms std
    (il faut alors inclure <cmath> pour garantir leur présence avec g ++).

Afin d'utiliser les surcharges d'espace de noms g ++ std sans qualification, une approche pratique consiste à définir des enveloppes d'en-têtes pour ce compilateur. J'ai utilisé cette approche pour corriger les lacunes de g ++ par rapport à. à la famille printf. Car, comme l'a fait remarquer David Wheeler, "tous les problèmes en informatique peuvent être résolus par un autre niveau d'indirection"…

Ensuite, les choses peuvent être arrangées de sorte que le code standard qui utilise les surcharges manquantes de g ++, se compile également avec g ++. Cela ajuste le compilateur à la norme, avec une quantité fixe de code.

41

Comme tout autre fichier d'en-tête, vous #include <cassert> Lorsque vous utilisez quelque chose déclaré dans ce fichier d'en-tête, comme assert().

8
Greg Hewgill

Voir un facilement accessible référence

#include <iostream>
// uncomment to disable assert()
// #define NDEBUG
#include <cassert>

int main()
{
    assert(2+2==4);
    std::cout << "Execution continues past the first assert\n";
    assert(2+2==5);
    std::cout << "Execution continues past the second assert\n";
}
0
TemplateRex

assert.h définit une fonction macro qui peut être utilisée comme outil de débogage standard.

0
Praveen Kishor