名前空間
変種
操作

constinit 指定子 (C++20 以降)

From cppreference.com
< cpp‎ | language
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
名前空間
指定子
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点数
文字 - 文字列 - nullptr (C++11)
ユーザー定義 (C++11)
ユーティリティ
属性 (C++11)
typedef宣言
型エイリアス宣言 (C++11)
キャスト
メモリ確保
クラス
クラス固有の関数プロパティ
explicit (C++11)
static

特殊メンバ関数
テンプレート
その他
 
 
  • constinit - 変数が静的初期化、すなわち ゼロ初期化 および 定数初期化 を持つことを表明する。そうでなければプログラムは不正な形式である。

目次

[編集] 説明

constinit 指定子は、静的またはスレッド ストレージ期間 を持つ変数を宣言する。

constinit 指定子は、構造化束縛 宣言にも適用できる。この場合、constinit は、宣言によって導入された 一意な名前を持つ変数 にも適用される。

(C++26以降)

変数が constinit で宣言されている場合、その 初期化宣言constinit を適用しなければならない。 constinit で宣言された変数が 動的初期化 を持つ場合 (たとえそれが 静的初期化として実行される としても)、プログラムは不正な形式である。

初期化宣言の時点で constinit 宣言に到達できない場合、プログラムは不正な形式であるが、診断は不要である。

constinitconstexpr と一緒に使用することはできない。宣言された変数が参照である場合、constinitconstexpr と等価である。宣言された変数がオブジェクトである場合、constexpr は、オブジェクトが静的初期化と定数デストラクタを持ち、オブジェクトを const 修飾することを義務付けるが、constinit は定数デストラクタと const 修飾を義務付けない。結果として、constexpr コンストラクタを持ち、constexpr デストラクタを持たない型 (例: std::shared_ptr<T>) のオブジェクトは、constinit で宣言できるが constexpr では宣言できない場合がある。

const char* g() { return "dynamic initialization"; }
constexpr const char* f(bool p) { return p ? "constant initializer" : g(); }
 
constinit const char* c = f(true);     // OK
// constinit const char* d = f(false); // error

constinit は、非初期化宣言でも使用でき、thread_local 変数がすでに初期化されていることをコンパイラに伝え、そうでなければ隠れたガード変数によって発生する オーバーヘッドを削減する ことができる。

extern thread_local constinit int x;
int f() { return x; } // no check of a guard variable needed

[編集] 注記

機能テストマクロ 規格 機能
__cpp_constinit 201907L (C++20) constinit

[編集] キーワード

constinit

[編集]

#include <cassert>
 
constexpr int square(int i)
{
    return i * i;
}
 
int twice(int i)
{
    return i + i;
}
 
constinit int sq = square(2);    // OK: initialization is done at compile time
// constinit int x_x = twice(2); // Error: compile time initializer required
 
int square_4_gen()
{
    static constinit int pow = square(4);
 
    // constinit int prev = pow; // Error: constinit can only be applied to a
                                 // variable with static or thread storage duration
    int prev = pow;
    pow = pow * pow;
    return prev;
}
 
int main()
{
    assert(sq == 4);
    sq = twice(1); // Unlike constexpr this value can be changed later at runtime
    assert(sq == 2);
 
    assert(square_4_gen() == 16);
    assert(square_4_gen() == 256);
    assert(square_4_gen() == 65536);
}

[編集] 欠陥報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
CWG 2543 C++20 constinit で宣言された変数の動作が不明確であった場合
静的初期化の一部として動的に初期化される
この場合、プログラムは
不正となる

[編集] 関連項目

consteval 指定子(C++20) 関数が即時関数であることを指定する。つまり、関数へのすべての呼び出しは定数評価内で行われなければならない。[編集]
constexpr 指定子(C++11) 変数または関数の値をコンパイル時に計算できることを指定する[編集]
ない コンパイル時に評価可能なを定義する
定数初期化 静的 変数の初期値をコンパイル時定数に設定する
ゼロ初期化 オブジェクトの初期値をゼロに設定する
English 日本語 中文(简体) 中文(繁體)