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

Especifica que la expresión dada se asume que siempre se evalúa como true en un punto determinado para permitir optimizaciones del compilador basadas en la información proporcionada.

Contenidos

Sintaxis

[ [ assume ( expresión ) ] ]
expression - cualquier expresión (excepto expresiones de coma sin paréntesis)

Explicación

[ [ assume ] ] solo puede aplicarse a una sentencia nula , como en [ [ assume ( x > 0 ) ] ] ; . Esta sentencia se denomina suposición .

expresión se convierte contextualmente a bool , pero no se evalúa (sigue siendo potencialmente evaluada ).

Notas

Dado que las suposiciones causan comportamiento indefinido en tiempo de ejecución si no se cumplen, deben usarse con moderación.

Una forma correcta de utilizarlos es seguir las aserciones con supuestos:

assert(x > 0);     // activa una aserción cuando NDEBUG no está definido y x > 0 es falso
[[assume(x > 0)]]; // proporciona oportunidades de optimización cuando NDEBUG está definido

Ejemplo

#include <cmath>
void f(int& x, int y)
{
    void g(int);
    void h();
    [[assume(x > 0)]]; // El compilador puede asumir que x es positivo
    g(x / 2); // Posiblemente se genere código más eficiente
    x = 3;
    int z = x;
    [[assume((h(), x == z))]]; // El compilador puede asumir que x mantendrá el mismo valor después
                               // de llamar a h
                               // La suposición no provoca una llamada a h
    h();
    g(x); // El compilador puede reemplazar esto con g(3);
    h();
    g(x); // El compilador NO puede reemplazar esto con g(3);
          // Una suposición solo se aplica en el punto donde aparece
    z = std::abs(y);
    [[assume((g(z), true))]]; // El compilador puede asumir que g(z) retornará
    g(z); // Debido a las suposiciones anteriores y posteriores, el compilador puede reemplazar esto con g(10);
    [[assume(y == -10)]]; // Comportamiento indefinido si y != -10 en este punto
    [[assume((x - 1) * 3 == 12)]];
    g(x); // El compilador puede reemplazar esto con g(5);
}

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Aplicado a Comportamiento publicado Comportamiento correcto
CWG 2924 C++23 violar una suposición resultaría en comportamiento indefinido resulta en comportamiento indefinido en tiempo de ejecución

Referencias

  • Estándar C++23 (ISO/IEC 14882:2024):
  • 9.12.3 Atributo de suposición [dcl.attr.assume]

Véase también

marca un punto de ejecución inalcanzable
(función)
contract_assert statement (C++26) verifica una condición interna durante la ejecución

Enlaces externos

1. Documentación de extensiones de lenguaje de Clang: __builtin_assume .
2. Documentación de referencia de atributos de Clang: assume .
3. Documentación de MSVC: __assume incorporado.
4. Documentación de GCC: __attribute__((assume(...))) .