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

Spécifie que l'expression donnée est supposée toujours s'évaluer à true à un point donné afin de permettre des optimisations du compilateur basées sur les informations fournies.

Table des matières

Syntaxe

[ [ assume ( expression ) ] ]
expression - toute expression (sauf les expressions virgule non parenthésées)

Explication

[ [ assume ] ] ne peut être appliqué qu'à une instruction nulle , comme dans [ [ assume ( x > 0 ) ] ] ; . Cette instruction est appelée une hypothèse .

expression est contextuellement convertie en bool , mais elle n'est pas évaluée (elle reste potentiellement évaluée ).

  • Si l'expression convertie expression s'évaluait à true au point où l'hypothèse apparaît, l'hypothèse n'a aucun effet.
  • Sinon, l'évaluation de l'hypothèse a un comportement indéfini à l'exécution .

Notes

Puisque les hypothèses provoquent un comportement indéfini à l'exécution si elles ne sont pas respectées, elles devraient être utilisées avec parcimonie.

Une manière correcte de les utiliser est de faire suivre les assertions par des hypothèses :

assert(x > 0);     // déclenche une assertion lorsque NDEBUG n'est pas défini et x > 0 est faux
[[assume(x > 0)]]; // fournit des opportunités d'optimisation lorsque NDEBUG est défini

Exemple

#include <cmath>
void f(int& x, int y)
{
    void g(int);
    void h();
    [[assume(x > 0)]]; // Le compilateur peut supposer que x est positif
    g(x / 2); // Code potentiellement plus efficace généré
    x = 3;
    int z = x;
    [[assume((h(), x == z))]]; // Le compilateur peut supposer que x conserve la même valeur après
                               // l'appel à h
                               // L'hypothèse ne provoque pas d'appel à h
    h();
    g(x); // Le compilateur peut remplacer ceci par g(3);
    h();
    g(x); // Le compilateur NE PEUT PAS remplacer ceci par g(3);
          // Une hypothèse s'applique uniquement au point où elle apparaît
    z = std::abs(y);
    [[assume((g(z), true))]]; // Le compilateur peut supposer que g(z) retournera
    g(z); // En raison des hypothèses ci-dessus et ci-dessous, le compilateur peut remplacer ceci par g(10);
    [[assume(y == -10)]]; // Comportement indéfini si y != -10 à ce point
    [[assume((x - 1) * 3 == 12)]];
    g(x); // Le compilateur peut remplacer ceci par g(5);
}

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Appliqué à Comportement tel que publié Comportement correct
CWG 2924 C++23 violer une hypothèse entraînait un comportement indéfini entraîne un comportement indéfini à l'exécution

Références

  • Norme C++23 (ISO/CEI 14882:2024) :
  • 9.12.3 Attribut d'hypothèse [dcl.attr.assume]

Voir aussi

marque un point d'exécution inaccessible
(fonction)
contract_assert statement (C++26) vérifie une condition interne durant l'exécution

Liens externes

1. Documentation des extensions de langage Clang : __builtin_assume .
2. Documentation de référence des attributs Clang : assume .
3. Documentation MSVC : __assume intrinsèque.
4. Documentation GCC : __attribute__((assume(...))) .