Пространства имён
Варианты
Действия

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

Материал из cppreference.com
 
 
Язык С++
Общие темы
Управление потоком
Операторы условного выполнения
if
Операторы итерации (циклы)
Операторы перехода
Функции
Объявление функции
Выражение лямбда-функции
Спецификатор inline
Спецификации динамических исключений (до C++17*)
Спецификатор noexcept (C++11)
Исключения
Пространства имён
Типы
Спецификаторы
decltype (C++11)
auto (C++11)
alignas (C++11)
Спецификаторы длительности хранения
Инициализация
Выражения
Альтернативные представления
Литералы
Логические - Целочисленные - С плавающей запятой
Символьные - Строковые - nullptr (C++11)
Определяемые пользователем (C++11)
Утилиты
Атрибуты (C++11)
Types
Объявление typedef
Объявление псевдонима типа (C++11)
Casts
Неявные преобразования - Явные преобразования
static_cast - dynamic_cast
const_cast - reinterpret_cast
Выделение памяти
Классы
Свойства функции класса
explicit (C++11)
static
Специальные функции-элементы
Шаблоны
Разное
 
Обьявления
Объявления
ссылка
указатель
массив
Block declarations
простое объявление
объявление структурных привязок (C++17)
объявление псевдонимов(C++11)
объявление псевдонимов пространств имён
using-declaration
директива using
объявление static_assert (C++11)
определение asm
объявление непрозрачного enum(C++11)
Другие объявления
определение пространств имён
объявление функции
объявление шаблона класса
объявление шаблона функции
явное инстанцирование шаблона(C++11)
явная специализация шаблона
спецификация связывания
объявление атрибута (C++11)
пустое объявление
 

Объяснение

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

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

const char *g() { return "динамическая инициализация"; }
constexpr const char *f(bool p) { return p ? "константный инициализатор" : g(); }

constinit const char *c = f(true); // OK
// constinit const char *d = f(false); // ошибка

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

extern thread_local constinit int x;
int f() { return x; } // не требуется проверка охранной переменной

Примечание

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

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

constinit

Пример

Отчёты о дефектах

Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:

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

Смотрите также

спецификатор consteval (C++20) указывает, что функция является немедленной функцией, то есть каждый вызов функции должен оцениваться константно[править]
спецификатор constexpr(C++11) указывает, что значение переменной или функции может быть вычислено во время компиляции[править]
константное выражение определяет выражение, которое может быть оценено во время компиляции
константная инициализация устанавливает начальные значения статических переменных равными константе времени компиляции
инициализация нулём устанавливает начальное значение объекта равным нулю
Morty Proxy This is a proxified and sanitized view of the page, visit original site.