static_assert Deklaration (seit C++11)
Führt Assertionsprüfungen zur Kompilierzeit durch.
Inhalt |
[bearbeiten] Syntax
static_assert( bool-constexpr , unevaluated-string ) |
(1) | ||||||||
static_assert( bool-constexpr ) |
(2) | (seit C++17) | |||||||
static_assert( bool-constexpr , constant-expression ) |
(3) | (seit C++26) | |||||||
Deklariert eine statische Assertion. Wenn die Assertion fehlschlägt, ist das Programm fehlerhaft und es kann eine diagnostische Fehlermeldung generiert werden.
[bearbeiten] Erklärung
| bool-constexpr | - |
| ||||
| unevaluated-string | - | ein nicht ausgewertetes String-Literal, das als Fehlermeldung erscheint. | ||||
| konstanter Ausdruck | - | ein konstanter Ausdruck msg, der alle folgenden Bedingungen erfüllt
|
Eine static_assert Deklaration kann im Namespace- und Block-Geltungsbereich (als Block-Deklaration) und innerhalb eines Klassenkörpers (als Mitgliedsdeklaration) erscheinen.
Wenn bool-constexpr wohlgeformt ist und zu true ausgewertet wird, oder im Kontext einer Template-Definition ausgewertet wird und das Template nicht instanziiert wird, hat diese Deklaration keine Auswirkung. Andernfalls wird ein Kompilierungsfehler ausgegeben und die vom Benutzer bereitgestellte Nachricht, falls vorhanden, wird in die Diagnosemeldung aufgenommen.
Der Text der vom Benutzer bereitgestellten Nachricht wird wie folgt bestimmt:
- Wenn die Nachricht den syntaktischen Anforderungen von unevaluated-string entspricht, ist der Text der Nachricht der Text des unevaluated-string.
|
(seit C++26) |
[bearbeiten] Hinweise
Der Standard schreibt nicht vor, dass ein Compiler den exakten Text der Fehlermeldung ausgibt, obwohl Compiler dies im Allgemeinen so weit wie möglich tun.
|
Da die Fehlermeldung ein String-Literal sein muss, kann sie keine dynamischen Informationen oder sogar einen konstanten Ausdruck enthalten, der selbst kein String-Literal ist. Insbesondere kann sie nicht den Namen des Template-Typarguments enthalten. |
(bis C++26) |
| Feature-Testmakro | Wert | Std | Feature |
|---|---|---|---|
__cpp_static_assert |
200410L |
(C++11) | static_assert (Syntax (1)) |
201411L |
(C++17) | static_assert mit einem Argument (Syntax (2)) | |
202306L |
(C++26) | vom Benutzer generierte Fehlermeldungen (Syntax (3)) |
[bearbeiten] Schlüsselwörter
[bearbeiten] Beispiel
#include <format> #include <type_traits> static_assert(03301 == 1729); // since C++17 the message string is optional template<class T> void swap(T& a, T& b) noexcept { static_assert(std::is_copy_constructible_v<T>, "Swap requires copying"); static_assert(std::is_nothrow_copy_constructible_v<T> && std::is_nothrow_copy_assignable_v<T>, "Swap requires nothrow copy/assign"); auto c = b; b = a; a = c; } template<class T> struct data_structure { static_assert(std::is_default_constructible_v<T>, "Data structure requires default-constructible elements"); }; template<class> constexpr bool dependent_false = false; // workaround before CWG2518/P2593R1 template<class T> struct bad_type { static_assert(dependent_false<T>, "error on instantiation, workaround"); static_assert(false, "error on instantiation"); // OK because of CWG2518/P2593R1 }; struct no_copy { no_copy(const no_copy&) = delete; no_copy() = default; }; struct no_default { no_default() = delete; }; #if __cpp_static_assert >= 202306L // Not real C++ yet (std::format should be constexpr to work): static_assert(sizeof(int) == 4, std::format("Expected 4, got {}", sizeof(int))); #endif int main() { int a, b; swap(a, b); no_copy nc_a, nc_b; swap(nc_a, nc_b); // 1 [[maybe_unused]] data_structure<int> ds_ok; [[maybe_unused]] data_structure<no_default> ds_error; // 2 }
Mögliche Ausgabe
1: error: static assertion failed: Swap requires copying 2: error: static assertion failed: Data structure requires default-constructible elements 3: error: static assertion failed: Expected 4, got 2
[bearbeiten] Defect reports
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| CWG 2039 | C++11 | nur der Ausdruck vor der Konvertierung muss konstant sein | die Konvertierung muss ebenfalls in einem konstanten Ausdruck gültig sein |
| CWG 2518 (P2593R1) |
C++11 | nicht instanziiertes static_assert(false, ""); war fehlerhaft | wurde wohlgeformt gemacht |
[bearbeiten] Referenzen
- C++23 Standard (ISO/IEC 14882:2024)
- 9.1 Preamble [dcl.pre] (p: 10)
- C++20 Standard (ISO/IEC 14882:2020)
- 9.1 Preamble [dcl.pre] (p: 6)
- C++17 Standard (ISO/IEC 14882:2017)
- 10 Declarations [dcl.dcl] (p: 6)
- C++14 Standard (ISO/IEC 14882:2014)
- 7 Declarations [dcl.dcl] (p: 4)
- C++11 Standard (ISO/IEC 14882:2011)
- 7 Declarations [dcl.dcl] (p: 4)
[bearbeiten] Siehe auch
| zeigt die angegebene Fehlermeldung an und macht das Programm fehlerhaft (Präprozessor-Direktive) | |
| bricht das Programm ab, wenn die vom Benutzer angegebene Bedingung nicht true ist. Kann für Release-Builds deaktiviert werden. (Funktionsmakro) | |
contract_assert-Anweisung (C++26) |
verifiziert eine interne Bedingung während der Ausführung |
| (C++11) |
entfernt bedingt eine Funktionsüberladung oder Template-Spezialisierung aus der Überladungsauflösung (Klassenvorlage) |
| Typ-Traits (C++11) | definieren Template-basierte Schnittstellen zur Kompilierzeit, um die Eigenschaften von Typen abzufragen. |
| C-Dokumentation für Statische Assertion
| |