Spec-Zone.ru › C++

constinit спецификатор (начиная с C++20)

  • constinit — утверждает, что переменная имеет статическую инициализацию, то есть инициализацию нулём и константную инициализацию, в противном случае программа некорректна.

Объяснение

Спецификатор constinit объявляет переменную со статической длительностью хранения или длительностью хранения потока.

Спецификатор constinit также может применяться к объявлениям структурированных привязок. В этом случае constinit также применяется к переменной с уникальным именем, введённой объявлением.

(начиная с C++26)

Если переменная объявлена с constinit, её объявление-инициализатор также должно содержать constinit. Если переменная, объявленная с constinit, имеет динамическую инициализацию (даже если она выполняется как статическая инициализация), программа некорректна.

Если в точке объявления-инициализатора недоступно ни одно объявление с constinit, программа некорректна; диагностика не требуется.

constinit нельзя использовать вместе с constexpr. Если объявленная переменная является ссылкой, constinit эквивалентен constexpr. Если объявленная переменная является объектом, constexpr требует, чтобы объект имел статическую инициализацию и константное уничтожение, а также делает объект константным, тогда как constinit не требует константного уничтожения и константности. В результате объект типа, у которого есть конструкторы constexpr, но нет деструктора constexpr (например, std::shared_ptr<T>), может быть объявлен с constinit, но не с constexpr.

const char* g() { return "dynamic initialization"; }
constexpr const char* f(bool p) { return p ? "constant initializer" : g(); }

constinit const char* c = f(true);     // OK
// constinit const char* d = f(false); // error

constinit также можно использовать в объявлении без инициализации, чтобы сообщить компилятору, что переменная thread_local уже инициализирована, уменьшая накладные расходы, которые в противном случае возникли бы из-за скрытой переменной-защитника.

extern thread_local constinit int x;
int f() { return x; } // no check of a guard variable needed

Примечания

Макрос проверки поддержки функции Значение Стандарт Функция
__cpp_constinit 201907L (C++20) constinit

Ключевые слова

constinit

Пример

#include <cassert>

constexpr int square(int i)
{
    return i * i;
}

int twice(int i)
{
    return i + i;
}

constinit int sq = square(2);    // OK: initialization is done at compile time
// constinit int x_x = twice(2); // Error: compile time initializer required

int square_4_gen()
{
    static constinit int pow = square(4);
    
    // constinit int prev = pow; // Error: constinit can only be applied to a
                                 // variable with static or thread storage duration
    int prev = pow;
    pow = pow * pow;
    return prev;
}

int main()
{
    assert(sq == 4);
    sq = twice(1); // Unlike constexpr this value can be changed later at runtime
    assert(sq == 2);
    
    assert(square_4_gen() == 16);
    assert(square_4_gen() == 256);
    assert(square_4_gen() == 65536);
}

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

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

DR Применяется к Опубликованное поведение Правильное поведение
CWG 2543 C++20 поведение было неясным, если переменная, объявленная с constinit,
динамически инициализировалась в рамках статической инициализации
в этом случае программа
некорректна

См. также

consteval спецификатор(C++20) указывает, что функция является непосредственной функцией, то есть каждый вызов функции должен находиться в контексте константного вычисления
constexpr спецификатор(C++11) указывает, что значение переменной или функции может быть вычислено во время компиляции
константное выражение определяет выражение, которое может быть вычислено во время компиляции
константная инициализация задаёт начальные значения статических переменных как константы времени компиляции
инициализация нулём задаёт начальное значение объекта равным нулю

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

Spec-Zone.ru

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