Namespaces
Variants

assert

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

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

1) Wenn NDEBUG als Makroname an der Stelle im Quellcode definiert ist, wo <cassert> oder <assert.h> eingebunden wird, ist die Assertion deaktiviert: assert führt keine Operation aus.
2) Andernfalls ist die Assertion aktiviert:

assert überprüft, ob sein Argument (welches skalaren Typ haben muss):

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

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

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

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

  • der Text von condition
(bis C++26)
  • #__VA_ARGS__
(seit C++26)

Der Ausdruck assert ( E ) ist garantiert ein konstantes Subexpression , wenn entweder

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

Inhaltsverzeichnis

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