Namespaces
Variants

assert

From cppreference.net
Défini dans l'en-tête <cassert>
Assertion désactivée
(1)
#define assert(condition) ((void)0)
(jusqu'en C++26)
#define assert(...)       ((void)0)
(depuis C++26)
Assertion activée
(2)
#define assert(condition) /* non spécifié */
(jusqu'en C++26)
#define assert(...)       /* non spécifié */
(depuis C++26)

La définition de la macro assert dépend d'une autre macro, NDEBUG , qui n'est pas définie par la bibliothèque standard.

1) Si NDEBUG est défini comme nom de macro au point du code source où <cassert> ou <assert.h> est inclus, l'assertion est désactivée : assert ne fait rien.
2) Sinon, l'assertion est activée :

assert vérifie si son argument (qui doit être de type scalaire) :

  • Si l'argument est différent de zéro, il n'y a pas d'autres effets.
  • Sinon, assert crée un diagnostic sur le flux d'erreur standard et appelle std::abort() .
(jusqu'à C++26)

assert insère un test de diagnostic dans les programmes et se développe en une expression de type void . __VA_ARGS__ est évalué et converti contextuellement en bool :

  • Si l'évaluation donne true , il n'y a pas d'autres effets.
  • Sinon, assert crée un diagnostic sur le flux d'erreur standard et appelle std::abort() .
(depuis C++26)

Les informations de diagnostic ont un format défini par l'implémentation, mais elles incluent toujours les informations suivantes :

  • le texte de condition
(jusqu'à C++26)
  • #__VA_ARGS__
(depuis C++26)
  • le nom du fichier source (c.-à-d., __FILE__ )
  • le numéro de ligne source (c.-à-d., __LINE__ )
  • le nom de la fonction englobante (c.-à-d., __func__ )

L'expression assert ( E ) est garantie d'être une sous-expression constante , si l'une des conditions suivantes est remplie :

  • NDEBUG est défini au point où assert est défini ou redéfini pour la dernière fois, ou
  • E , converti contextuellement en bool , est une sous-expression constante qui s'évalue à true .
(depuis C++11)

Table des matières

Paramètres

condition - expression de type scalaire

Notes

Étant donné que assert est une macro de type fonction , les virgules présentes dans l'argument qui ne sont pas protégées par des parenthèses sont interprétées comme des séparateurs d'arguments de macro. De telles virgules se trouvent souvent dans les listes d'arguments de templates et l'initialisation de liste :

assert(std::is_same_v<int, int>);        // error: assert does not take two arguments
assert((std::is_same_v<int, int>));      // OK: one argument
static_assert(std::is_same_v<int, int>); // OK: not a macro
std::complex<double> c;
assert(c == std::complex<double>{0, 0});   // error
assert((c == std::complex<double>{0, 0})); // OK
(jusqu'à C++26)

Il n'existe pas d'interface standardisée pour ajouter un message supplémentaire aux erreurs assert . Une méthode portable pour en inclure un est d'utiliser un opérateur virgule à condition qu'il n'ait pas été surchargé , ou d'utiliser && avec un littéral de chaîne :

assert(("Il y a cinq lumières", 2 + 2 == 5));
assert(2 + 2 == 5 && "Il y a cinq lumières");

L'implémentation de assert dans Microsoft CRT n'est pas conforme au C++11 et aux révisions ultérieures, car sa fonction sous-jacente ( _wassert ) n'accepte ni __func__ ni un remplacement équivalent.

Depuis C++20, les valeurs nécessaires pour le message de diagnostic peuvent également être obtenues à partir de std::source_location::current() .

Bien que le changement de assert dans C23/C++26 ne soit pas formellement un rapport de défaut, le comité C recommande aux implémentations de rétroporter le changement aux anciens modes.

Exemple

#include <iostream>
// décommenter pour désactiver assert()
// #define NDEBUG
#include <cassert>
// Utiliser (void) pour ignorer les avertissements de variables inutilisées.
#define assertm(exp, msg) assert((void(msg), exp))
int main()
{
    assert(2 + 2 == 4);
    std::cout << "Point de contrôle #1\n";
    assert((void("void aide à éviter l'avertissement 'valeur inutilisée'"), 2 * 2 == 4));
    std::cout << "Point de contrôle #2\n";
    assert((010 + 010 == 16) && "Une autre façon d'ajouter un message d'assertion");
    std::cout << "Point de contrôle #3\n";
    assertm((2 + 2) % 3 == 1, "Succès");
    std::cout << "Point de contrôle #4\n";
    assertm(2 + 2 == 5, "Échec"); // l'assertion échoue
    std::cout << "L'exécution continue après la dernière assertion\n"; // Aucune sortie
}

Sortie possible :

Point de contrôle #1
Point de contrôle #2
Point de contrôle #3
Point de contrôle #4
main.cpp:23: int main(): Assertion `((void)"Échec", 2 + 2 == 5)' failed.
Aborted

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Appliqué à Comportement publié Comportement corrigé
LWG 2234 C++11 assert ne pouvait pas être utilisé dans une expression constante peut être utilisé

Voir aussi

contract_assert instruction (C++26) vérifie une condition interne durant l'exécution
static_assert déclaration (C++11) effectue une vérification d'assertion à la compilation
provoque la terminaison anormale du programme (sans nettoyage)
(fonction)
Documentation C pour assert