Spec-Zone.ru › C++

Инициализация констант

Устанавливает начальные значения статических переменных до значения константы времени компиляции.

Объяснение

Если статическая или локальная для потока(с C++11) переменная инициализируется константой (см. ниже), выполняется инициализация константой вместо инициализации нулём до всех остальных инициализаций.

Переменная или временный объект obj считается инициализируемой константой, если

  • либо у неё есть инициализатор, либо её инициализация по умолчанию приводит к выполнению какой-либо инициализации, и
  • её полное выражение инициализации полное выражение является постоянным выражением, за исключением того, что если obj является объектом, это полное выражение может также вызывать constexpr конструкторы для obj и его подобъектов, даже если эти объекты являются типами классов, не являющимися литеральными(с C++11).

Эффекты инициализации константой аналогичны эффектам соответствующей инициализации, за исключением того, что гарантируется, что она завершена до начала любой другой инициализации статического или локального для потока(с C++11) объекта, и она может выполняться во время компиляции.

Примечания

Компилятор может инициализировать другие статические и локальные для потока(с C++11) объекты с помощью инициализации константой, если он может гарантировать, что значение будет таким же, как если бы соблюдалась стандартная последовательность инициализации.

На практике инициализация константой выполняется во время компиляции, и предварительно рассчитанные представления объектов хранятся как часть образа программы (например, в разделе .data). Если переменная является одновременно const и инициализируется константой, её представление объекта может храниться в разделе только для чтения образа программы (например, в разделе .rodata).

Пример

#include <iostream>
#include <array>
 
struct S
{
    static const int c;
};
 
const int d = 10 * S::c; // not a constant expression: S::c has no preceding
                         // initializer, this initialization happens after const
const int S::c = 5;      // constant initialization, guaranteed to happen first
 
int main()
{
    std::cout << "d = " << d << '\n';
    std::array<int, S::c> a1; // OK: S::c is a constant expression
//  std::array<int, d> a2;    // error: d is not a constant expression
}

Вывод:

d = 50

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

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

DR Применимо к Поведение, как опубликовано Корректное поведение
CWG 441 C++98 ссылки не могли быть инициализированы константой сделаны инициализируемыми константой
CWG 1489 C++98 не было ясно, может ли инициализация значения объекта быть инициализацией константой может
CWG 1747 C++98 связывание ссылки с функцией не могло быть инициализацией константой может
CWG 1834 C++11 связывание ссылки с xvalue не могло быть инициализацией константой может
CWG 2026 C++98 инициализация нулём всегда должна выполняться первой, даже до инициализации константой нет инициализации нулём, если применяется инициализация константой
CWG 2366 C++98 инициализация по умолчанию не могла быть инициализацией константой (требовались инициализаторы константы) может

См. также

  • constexpr
  • конструктор
  • конвертирующий конструктор
  • конструктор копирования
  • конструктор по умолчанию
  • explicit
  • инициализация
    • инициализация агрегатов
    • копирующая инициализация
    • инициализация по умолчанию
    • прямая инициализация
    • инициализация списком
    • инициализация ссылок
    • инициализация значением
    • инициализация нулём
  • конструктор перемещения

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

Spec-Zone.ru

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