Спецификатор constinit (начиная с C++20)
constinit- утверждает, что переменная имеет статическую инициализацию, т.е. инициализацию нулём и константную инициализацию, в противном случае программа некорректна.
Объяснение
Спецификатор 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
|
Ключевые слова
Пример
| Этот раздел не завершён Причина: нет примера |
Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| CWG 2543 | C++20 | поведение было неясным, если переменная, объявленная с помощью constinit, была динамически инициализирована как часть статической инициализации
|
в этом случае программа некорректна |
Смотрите также
спецификатор consteval (C++20)
|
указывает, что функция является немедленной функцией, то есть каждый вызов функции должен оцениваться константно |
спецификатор constexpr(C++11)
|
указывает, что значение переменной или функции может быть вычислено во время компиляции |
| константное выражение | определяет выражение, которое может быть оценено во время компиляции |
| константная инициализация | устанавливает начальные значения статических переменных равными константе времени компиляции |
| инициализация нулём | устанавливает начальное значение объекта равным нулю |