Namespaces
Variants

C++ attribute: assume (since C++23)

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

Gibt an, dass angenommen wird, dass der gegebene Ausdruck an einem bestimmten Punkt immer zu true ausgewertet wird, um Compiler-Optimierungen auf Basis der gegebenen Informationen zu ermöglichen.

Inhaltsverzeichnis

Syntax

[ [ assume ( Ausdruck ) ] ]
expression - beliebiger Ausdruck (außer nicht in Klammern gesetzte Komma-Ausdrücke )

Erklärung

[ [ assume ] ] kann nur auf eine Null-Anweisung angewendet werden, wie in [ [ assume ( x > 0 ) ] ] ; . Diese Anweisung wird als Annahme bezeichnet.

expression wird kontextuell zu bool konvertiert , aber es wird nicht ausgewertet (es bleibt potenziell ausgewertet ).

  • Wenn der konvertierte Ausdruck an der Stelle, an der die Annahme erscheint, zu true ausgewertet werden würde, hat die Annahme keine Wirkung.
  • Andernfalls hat die Auswertung der Annahme Laufzeit-undefiniertes Verhalten .

Hinweise

Da Annahmen zu Laufzeit-undefiniertem Verhalten führen, wenn sie nicht zutreffen, sollten sie sparsam eingesetzt werden.

Eine korrekte Verwendungsweise besteht darin, Assertions mit Assumptions zu kombinieren:

assert(x > 0);     // löst eine Assertion aus, wenn NDEBUG nicht definiert ist und x > 0 falsch ist
[[assume(x > 0)]]; // bietet Optimierungsmöglichkeiten, wenn NDEBUG definiert ist

Beispiel

#include <cmath>
void f(int& x, int y)
{
    void g(int);
    void h();
    [[assume(x > 0)]]; // Compiler kann annehmen, dass x positiv ist
    g(x / 2); // Möglicherweise effizienterer Code generiert
    x = 3;
    int z = x;
    [[assume((h(), x == z))]]; // Compiler kann annehmen, dass x nach
                               // Aufruf von h denselben Wert hat
                               // Die Annahme verursacht keinen Aufruf von h
    h();
    g(x); // Compiler kann dies durch g(3) ersetzen
    h();
    g(x); // Compiler darf dies NICHT durch g(3) ersetzen
          // Eine Annahme gilt nur an der Stelle, an der sie erscheint
    z = std::abs(y);
    [[assume((g(z), true))]]; // Compiler kann annehmen, dass g(z) zurückkehrt
    g(z); // Aufgrund obiger und folgender Annahmen kann Compiler dies durch g(10) ersetzen
    [[assume(y == -10)]]; // Undefiniertes Verhalten wenn y != -10 an dieser Stelle
    [[assume((x - 1) * 3 == 12)]];
    g(x); // Compiler kann dies durch g(5) ersetzen
}

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
CWG 2924 C++23 Verletzung einer Annahme würde undefiniertes Verhalten verursachen führt zu laufzeit-undefiniertem Verhalten

Referenzen

  • C++23-Standard (ISO/IEC 14882:2024):
  • 9.12.3 Annahme-Attribut [dcl.attr.assume]

Siehe auch

markiert unerreichbaren Punkt der Ausführung
(Funktion)
contract_assert statement (C++26) verifiziert eine interne Bedingung während der Ausführung

Externe Links

1. Clang-Spracherweiterungsdokumentation: __builtin_assume .
2. Clang-Attributreferenzdokumentation: assume .
3. MSVC-Dokumentation: __assume Built-in.
4. GCC-Dokumentation: __attribute__((assume(...))) .