Namespaces
Variants

static_assert declaration (since C++11)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Führt Überprüfungen zur Compile-Zeit durch.

Inhaltsverzeichnis

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.

1) Eine statische Assertion mit festgelegter Fehlermeldung.
2) Eine statische Assertion ohne Fehlermeldung.
3) Eine statische Assertion mit benutzerdefinierter Fehlermeldung.
Diese Syntax kann nur übereinstimmen, wenn Syntax ( 1 ) nicht übereinstimmt.

Erklärung

bool-constexpr -

ein kontextuell umgewandelter konstanter Ausdruck vom Typ bool . Eingebaute Konvertierungen sind nicht erlaubt, außer nicht- einschränkenden integralen Konvertierungen zu bool .

(bis C++23)

ein Ausdruck kontextuell umgewandelt zu bool , wobei die Konvertierung ein konstanter Ausdruck ist

(seit C++23)
unevaluated-string - ein nicht ausgewertetes Zeichenkettenliteral , das als Fehlermeldung erscheinen wird
constant-expression - ein konstanter Ausdruck msg , der alle folgenden Bedingungen erfüllt:
  • msg. size ( ) ist implizit konvertierbar zu std::size_t .
  • msg. data ( ) ist implizit konvertierbar zu const char * .

Eine static_assert -Deklaration kann im Namensraum- und Block- Scope erscheinen (als eine Blockdeklaration ) und innerhalb eines Klassenkörpers (als eine Memberdeklaration ).

Wenn bool-constexpr wohlgeformt ist und zu true ausgewertet wird, oder im Kontext einer Templatedefinition ausgewertet wird und das Template nicht instanziiert ist, hat diese Deklaration keine Wirkung. Andernfalls wird ein Kompilierzeitfehler ausgegeben, und die benutzerdefinierte 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 eines unevaluated-string entspricht, ist der Text der Nachricht der Text des unevaluated-string .
  • Andernfalls, gegeben die folgenden Werte:
Der Text der Nachricht wird gebildet durch die Sequenz von len Codeeinheiten , beginnend bei ptr , der gewöhnlichen Literal-Codierung . Für jede ganze Zahl i in [ 0 , len ) muss ptr [ i ] ein integraler Konstantenausdruck sein.
(seit C++26)

Hinweise

Der Standard verlangt nicht, dass ein Compiler den exakten Text der Fehlermeldung ausgibt, obwohl Compiler dies im Allgemeinen so weit wie möglich tun.

Da die Fehlermeldung ein Zeichenkettenliteral sein muss, kann sie keine dynamischen Informationen oder sogar einen konstanten Ausdruck enthalten, der nicht selbst ein Zeichenkettenliteral ist. Insbesondere kann sie nicht den Namen des Template-Typarguments enthalten.

(bis C++26)
Feature-Test-Makro Wert Std Feature
__cpp_static_assert 200410L (C++11) static_assert (Syntax ( 1 ) )
201411L (C++17) Einargument- static_assert (Syntax ( 2 ) )
202306L (C++26) Benutzerdefinierte Fehlermeldungen (Syntax ( 3 ) )

Schlüsselwörter

static_assert

Beispiel

#include <format>
#include <type_traits>
static_assert(03301 == 1729); // seit C++17 ist die Nachrichten-Zeichenkette 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 vor CWG2518/P2593R1
template<class T>
struct bad_type
{
    static_assert(dependent_false<T>, "error on instantiation, workaround");
    static_assert(false, "error on instantiation"); // OK wegen 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
// Noch kein echtes C++ (std::format müsste constexpr sein, um zu funktionieren):
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: Fehler: Static Assertion fehlgeschlagen: Swap requires copying
2: Fehler: Static Assertion fehlgeschlagen: Data structure requires default-constructible elements
3: Fehler: Static Assertion fehlgeschlagen: Expected 4, got 2

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
CWG 2039 C++11 nur der Ausdruck vor der Konvertierung musste konstant sein die Konvertierung muss ebenfalls
in einem konstanten Ausdruck gültig sein
CWG 2518
( P2593R1 )
C++11 nicht instanziierte static_assert ( false , "" ) ; war fehlerhaft als korrekt definiert

Referenzen

  • C++23-Standard (ISO/IEC 14882:2024):
  • 9.1 Präambel [dcl.pre] (S.: 10)
  • C++20-Standard (ISO/IEC 14882:2020):
  • 9.1 Präambel [dcl.pre] (S.: 6)
  • C++17-Standard (ISO/IEC 14882:2017):
  • 10 Deklarationen [dcl.dcl] (S.: 6)
  • C++14-Standard (ISO/IEC 14882:2014):
  • 7 Deklarationen [dcl.dcl] (S.: 4)
  • C++11-Standard (ISO/IEC 14882:2011):
  • 7 Deklarationen [dcl.dcl] (S: 4)

Siehe auch

zeigt die angegebene Fehlermeldung an und macht das Programm fehlerhaft
(Präprozessor-Direktive)
bricht das Programm ab, wenn die benutzerdefinierte Bedingung nicht true ist. Kann für Release-Builds deaktiviert werden.
(Funktionsmakro)
contract_assert statement (C++26) überprüft eine interne Bedingung während der Ausführung
(C++11)
entfernt bedingt eine Funktionsüberladung oder Templatespezialisierung aus der Überladungsauflösung
(Klassentemplate)
Type traits (C++11) definiert kompilierzeit-template-basierte Schnittstellen zum Abfragen von Typeigenschaften
C-Dokumentation für Statische Assertion