Namensräume
Varianten
Aktionen

assert

Von cppreference.com
< cpp‎ | error
 
 
 
Definiert in 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) /* nicht spezifiziert */
(bis C++26)
#define assert(...)       /* nicht spezifiziert */
(seit C++26)

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

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

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

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

assert fügt Diagnoseprüfungen 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 Effekte.
  • Andernfalls erzeugt assert eine Diagnose auf dem Standardfehlerstrom und ruft std::abort() auf.
(seit C++26)

Die Diagnoseinformationen haben ein implementierungsdefiniertes Format, aber sie enthalten immer die folgenden Informationen:

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

Der Ausdruck assert(E) ist garantiert eine konstante Unterexpression, wenn entweder

  • NDEBUG an der Stelle definiert ist, an der assert zuletzt definiert oder neu definiert wurde, oder
  • E, kontextuell in bool konvertiert, eine konstante Unterexpression ist, die zu true ausgewertet wird.
(seit C++11)

Inhalt

[bearbeiten] Parameter

condition - Ausdruck vom skalaren Typ

[bearbeiten] Hinweise

Da assert ein funktionsartiges Makro ist, werden Kommas irgendwo im Argument, die nicht durch Klammern geschützt sind, als Trennzeichen für Makroargumente interpretiert. Solche Kommas finden sich häufig in Template-Argumentlisten und Initialisierungslisten.

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. Eine portable Möglichkeit, eine hinzuzufügen, ist die Verwendung eines Komma-Operators, vorausgesetzt, er wurde nicht überladen, oder die Verwendung von && mit einem String-Literal.

assert(("There are five lights", 2 + 2 == 5));
assert(2 + 2 == 5 && "There are five lights");

Die Implementierung von assert in der Microsoft CRT entspricht nicht C++11 und späteren Revisionen, da ihre zugrunde liegende Funktion (_wassert) weder __func__ noch einen äquivalenten 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 kein formeller Fehlerbericht ist, empfiehlt das C-Komitee Implementierungen, die Änderung in alte Modi zurückzuportieren.

[bearbeiten] Beispiel

#include <iostream>
// uncomment to disable assert()
// #define NDEBUG
#include <cassert>
 
// Use (void) to silence unused warnings.
#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 fails
    std::cout << "Execution continues past the last assert\n"; // No output
}

Mögliche Ausgabe

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

[bearbeiten] Fehlerberichte

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

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 2234 C++11 assert konnte nicht in einer konstanten Expression verwendet werden kann verwendet werden

[bearbeiten] Siehe auch

contract_assert-Anweisung (C++26) verifiziert eine interne Bedingung während der Ausführung[edit]
static_assert Deklaration (C++11) führt Assertionsprüfungen zur Kompilierzeit durch[bearbeiten]
verursacht abnormalen Programmabbruch (ohne Bereinigung)
(funktion) [bearbeiten]
C-Dokumentation für assert