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

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

Материал из cppreference.com
< cpp‎ | language
 
 
Язык С++
Общие темы
Управление потоком
Операторы условного выполнения
Операторы итерации (циклы)
Операторы перехода
Функции
Объявление функции
Выражение лямбда-функции
Спецификатор 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
Выделение памяти
Классы
Свойства функции класса
Специальные функции-элементы
Шаблоны
Разное
 
 

Содержание

[править] Объяснение

Спецификатор 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_constinit201907L(C++20)constinit

[править] Ключевые слова

constinit

[править] Пример

[править] Отчёты о дефектах

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

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

[править] Смотрите также

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