Spec-Zone.ru › C++

Атрибут C++: assume (с C++23)

Указывает, что заданное выражение в определённой точке считается всегда вычисляющимся в true, что позволяет компилятору выполнять оптимизации на основе предоставленной информации.

Синтаксис

[[assume( expression )]]
expression - любое выражение (кроме выражений с встроенным оператором запятая без скобок)

Пояснение

[[assume]] можно применить только к пустому оператору, как в [[assume(x > 0)]];. Такой оператор называется предположением.

expression контекстно преобразуется к bool, но не вычисляется (при этом оно по-прежнему потенциально вычисляемое).

  • Если преобразованное expression вычислялось бы в true в точке появления предположения, предположение не оказывает никакого эффекта.
  • В противном случае вычисление предположения приводит к неопределённому поведению во время выполнения.

Примечания

Поскольку невыполнение предположений приводит к неопределённому поведению во время выполнения, использовать их следует экономно.

Один из корректных способов их применения — добавлять предположения после проверок:

assert(x > 0);     // trigger an assertion when NDEBUG is not defined and x > 0 is false
[[assume(x > 0)]]; // provide optimization opportunities when NDEBUG is defined

Пример

#include <cmath>

void f(int& x, int y)
{
    void g(int);
    void h();
    
    [[assume(x > 0)]]; // Compiler may assume x is positive
    
    g(x / 2); // More efficient code possibly generated
    
    x = 3;
    int z = x;
    
    [[assume((h(), x == z))]]; // Compiler may assume x would have the same value after
                               // calling h
                               // The assumption does not cause a call to h
    
    h();
    g(x); // Compiler may replace this with g(3);
    
    h();
    g(x); // Compiler may NOT replace this with g(3);
          // An assumption applies only at the point where it appears
    
    z = std::abs(y);
    
    [[assume((g(z), true))]]; // Compiler may assume g(z) will return
    
    g(z); // Due to above and below assumptions, compiler may replace this with g(10);
    
    [[assume(y == -10)]]; // Undefined behavior if y != -10 at this point
    
    [[assume((x - 1) * 3 == 12)]];
    
    g(x); // Compiler may replace this with g(5);
}

Отчёты об ошибках

Следующие отчёты об ошибках, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам C++.

DR Применён к Опубликованное поведение Корректное поведение
CWG 2924 C++23 нарушение предположения приводило к неопределённому поведению приводит к неопределённому поведению во время выполнения

Ссылки

  • Стандарт C++23 (ISO/IEC 14882:2024):
    • 9.12.3 Атрибут предположения [dcl.attr.assume]

См. также

unreachable
(C++23)
обозначает недостижимую точку выполнения
(функция)
contract_assert оператор (C++26) проверяет внутреннее условие во время выполнения

Внешние ссылки

1. Документация по расширениям языка Clang: __builtin_assume.
2. Документация по атрибутам Clang: assume.
3. Документация MSVC: встроенная функция __assume.
4. Документация GCC: __attribute__((assume(...))).

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/language/attributes/assume

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API