Namespaces
Variants

assert

Von de.cppreference.net
 
 
 
Definiert in Header <cassert>
Deaktivierte Assertion
#define assert(condition) ((void)0)
(1) (bis C++26)
#define assert(...)       ((void)0)
(seit C++26)
Aktivierte Assertion
#define assert(condition) /* unspecified */
(2) (bis C++26)
#define assert(...)       /* unspecified */
(seit C++26)

Die Definition des Makros assert hängt von einem anderen Makro, NDEBUG, ab, das nicht von der Standardbibliothek definiert wird.

1) Wenn NDEBUG an der Stelle im Quellcode, an der <cassert> oder <assert.h> eingebunden wird, als Makroname definiert ist, wird die Assertion deaktiviert: assert bewirkt nichts.
2) Andernfalls ist die Assertion aktiviert:

assert prüft sein Argument (das einen skalaren Typ haben muss):

  • Wenn das Argument ungleich Null ist, gibt es keine weiteren Auswirkungen.
  • Andernfalls erstellt assert eine Diagnose auf dem Standardfehlerstrom und ruft std::abort() auf.
(bis C++26)

assert fügt einen Diagnosetest in Programme ein und expandiert zu einem Ausdruck vom Typ void. __VA_ARGS__ wird ausgewertet und kontextuell in bool konvertiert:

  • Wenn die Auswertung true ergibt, gibt es keine weiteren Auswirkungen.
  • Andernfalls erstellt assert eine Diagnose auf dem Standardfehlerstrom und ruft std::abort() auf.
(seit C++26)

Die Diagnoseinformationen haben ein implementationsdefiniertes Format, enthalten jedoch stets die folgenden Informationen:

  • den Text von condition
(bis C++26)
  • #__VA_ARGS__
(seit C++26)
  • den Quelldateinamen (d.h., __FILE__)
  • die Quellzeilennummer (d.h., __LINE__)
  • den Namen der umschließenden Funktion (d.h., __func__)

Der Ausdruck assert(E) ist garantiert ein konstanter Teilausdruck, wenn entweder

  • NDEBUG an der Stelle definiert ist, an der assert zuletzt definiert oder neu definiert wird, oder
  • E, kontextuell in bool konvertiert, ein konstanter Teilausdruck ist, der zu true ausgewertet wird.
(seit C++11)

Parameter

Bedingung - Ausdruck skalaren Typs

Hinweise

Da assert ein funktionsartiges Makro ist, werden Kommas im Argument, die nicht durch Klammern geschützt sind, als Makroargumenttrenner interpretiert. Solche Kommas finden sich häufig in Template-Argumentlisten und List-Initialisierungen:

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
(bis C++26)

Es gibt keine standardisierte Schnittstelle, um eine zusätzliche Nachricht zu assert -Fehlern hinzuzufügen. Ein portabler Weg, eine einzufügen, ist die Verwendung eines Komma-Operators , sofern dieser nicht überladen wurde, oder die Verwendung von && mit einem String-Literal:

assert(("Es gibt fünf Lichter", 2 + 2 == 5));
assert(2 + 2 == 5 && "Es gibt fünf Lichter");

Die Implementierung von assert im Microsoft CRT entspricht nicht C++11 und späteren Revisionen, da ihre zugrundeliegende Funktion ( _wassert ) weder __func__ noch einen gleichwertigen Ersatz akzeptiert.

Seit C++20 können die für die Diagnosemeldung benötigten Werte auch von std::source_location::current() bezogen werden.

Obwohl die Änderung von assert in C23/C++26 formal kein Defect Report ist, empfiehlt das C-Komitee Implementierungen, diese Änderung auf alte Modi zurückzuportieren.

Beispiel

#include <iostream>
// auskommentieren um assert() zu deaktivieren
// #define NDEBUG
#include <cassert>
// Verwende (void) um unbenutzte Warnungen zu unterdrücken.
#define assertm(exp, msg) assert((void(msg), exp))
int main()
{
    assert(2 + 2 == 4);
    std::cout << "Checkpoint #1\n";
    assert((void("void helps to avoid 'unused value' warning"), 2 * 2 == 4));
    std::cout << "Checkpoint #2\n";
    assert((010 + 010 == 16) && "Yet another way to add an assert message");
    std::cout << "Checkpoint #3\n";
    assertm((2 + 2) % 3 == 1, "Success");
    std::cout << "Checkpoint #4\n";
    assertm(2 + 2 == 5, "Failed"); // Assertion schlägt fehl
    std::cout << "Execution continues past the last assert\n"; // Keine Ausgabe
}

Mögliche Ausgabe:

Checkpoint #1
Checkpoint #2
Checkpoint #3
Checkpoint #4
main.cpp:23: int main(): Assertion `((void)"Failed", 2 + 2 == 5)' failed.
Aborted

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrektes Verhalten
LWG 2234 C++11 assert konnte nicht in konstanten Ausdrücken verwendet werden kann verwendet werden

Siehe auch

contract_assert statement (C++26) überprüft eine interne Bedingung während der Ausführung
static_assert declaration (C++11) führt Überprüfungen zur Übersetzungszeit durch
verursacht abnormale Programmbeendigung (ohne Bereinigung)
(Funktion)
C-Dokumentation für assert