C++2a(C++20)で導入予定のDesignated Initialization(指示付きの初期化)ついてメモ。C99での同一言語機能をベースとするが、一部機能制限された形でC++に導入される。
// C++2a(C++20) struct Point { int x, y; }; void f(Point); f({ .x = 100, .y = 50 }); // OK: Designated Initialization // 指示子順==メンバ宣言順 が条件 f({ .y = 50, .x = 100 }); // NG
C++2a言語機能とC99言語機能との差異は下表の通り(P0329R0より引用)。特に初期化子順序をデータメンバ宣言順と一致させる必要がある点に注意。関数呼び出しの名前付きパラメータ(named parameter)的な利用方法には使いづらそう。
C++2a | C99 | コード例 |
---|---|---|
指示子順とメンバ宣言順の一致が必要 | 指示子順序は任意 | C99ではOK/C++2aではNGstruct { int a, b; }; A a = { .b = 3, .a = 4 }; |
指示付き初期化の評価順序は左から右 | 初期化の評価順序は未規定*1 *2 | |
全て指示付き、または全て指示無し | 混在可能 | C99ではOK/C++2aではNGA a = { 3, .a = 4 }; |
指示付き初期化は重複不可 | 重複可能 | C99ではOK/C++2aではNGA a = { .a = 3, .a = 4 }; |
配列型には非対応 | 配列要素の初期化に対応 | C99ではOK/C++2aではNGA a = { [3] = 4 }; |
指示付き初期化のネスト不可 | ネスト対応 | C99ではOK/C++2aではNGA a = { .e.a = 3 }; |
統一初期化に対応 | (Cの初期化子のみ) | C++2aのみOKA a = { .a{} }; |
Working Draft N4687 C.1.7, 11.6.1より引用。
Change: In C++, designated initialization support is restricted compared to the corresponding functionality in C. In C++, designators for non-static data members must be specified in declaration order, designators for array elements and nested designators are not supported, and designated and non-designated initializers cannot be mixed in the same initializer list.
Example:struct A { int x, y; }; struct B { struct A a; }; struct A a = {.y = 1, .x = 2}; // valid C, invalid C++ int arr[3] = {[1] = 5}; // valid C, invalid C++ struct B b = {.a.x = 0}; // valid C, invalid C++ struct A c = {.x = 1, 2}; // valid C, invalid C++Rationale: In C++, members are destroyed in reverse construction order and the elements of an initializer list are evaluated in lexical order, so field initializers must be specified in order. Array designators conflict with lambda-expression syntax. Nested designators are seldom used.
N4687 Working Draft, Standard for Programming Language C++
Effect on original feature: Deletion of feature that is incompatible with C++.
Difficulty of converting: Syntactic transformation.
How widely used: Out-of-order initializers are common. The other features are seldom used.
関連URL
- (PDF)P0329R0 Designated Initialization
- (PDF)P0329R4 Designated Initialization Wording
- c++ - Why does C++11 not support designated initializer lists as C99? - Stack Overflow
- プログラミング言語Cの新機能, 指示付きの初期化子(Designated Initializer)
*1:C99 6.7.8/p23: The order in which any side effects occur among the initialization list expressions is unspecified.
*2:C11 6.7.9/p23: The evaluations of the initialization list expressions are indeterminately sequenced with respect to one another and thus the order in which any side effects occur is unspecified.