Namespaces
Variants

Constant initialization

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

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

Содержание

Объяснение

Постоянная инициализация выполняется в следующих случаях:

  • Инициализация объекта POD-типа со статической продолжительностью хранения с помощью константного выражения.
(до C++11)
  • Инициализация ссылки со статической или потоковой продолжительностью хранения, где удовлетворены все следующие условия:
  • lvalue, обозначающее объект со статической продолжительностью хранения
  • временный объект
  • подобъект временного объекта
  • функция
  • Инициализация объекта со статической или потоковой продолжительностью хранения, и удовлетворено одно из следующих условий:
  • Если объект инициализируется вызовом конструктора, где полное выражение инициализации является константным выражением, за исключением того, что оно также может вызывать constexpr конструкторы для объекта и его подобъектов (даже если эти объекты имеют не- литеральные типы классов).
  • В противном случае, либо объект инициализируется по значению , либо каждое полное выражение, присутствующее в его инициализаторе, является константным выражением.
(начиная с C++11)
(до C++17)
(начиная с C++17)
(до C++20)
(начиная с C++20)

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

Примечания

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

Постоянная инициализация обычно происходит при загрузке программы в память, как часть инициализации среды выполнения программы.

Пример

#include <iostream>
#include <array>
struct S
{
    static const int c;
};
const int d = 10 * S::c; // не константное выражение: S::c не имеет предшествующего
                         // инициализатора, эта инициализация происходит после const
const int S::c = 5;      // константная инициализация, гарантированно выполняется первой
int main()
{
    std::cout << "d = " << d << '\n';
    std::array<int, S::c> a1; // OK: S::c является константным выражением
//  std::array<int, d> a2;    // ошибка: d не является константным выражением
}

Вывод:

d = 50

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

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

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

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