1. ホーム
  2. c++

CとC++ : 自動構造体の部分的な初期化

2023-08-17 16:34:57

質問

例えば somestruct が3つの整数メンバを持つ場合、私はずっとC(またはC++)の関数でこれをやってもいいと思っていました。

somestruct s = {123,};

最初のメンバーは123に、最後の2つは0に初期化されます。 私はよく自動配列で同じことをして、次のように書きます。 int arr[100] = {0,}; と書いて、配列内のすべての整数が0に初期化されるようにします。



最近、私は GNU C リファレンスマニュアル というのを読みました。

構造体変数を初期化しない場合、その効果は次のようになります。 静的ストレージ(ストレージクラス指定子参照)かどうかによります。 によって異なります。構造体変数が静的ストレージを持つ場合、整数型のメンバは0で初期化され、ポインタのメンバはNULLで初期化されます。 ポインタのメンバはNULLに初期化されます。 構造体のメンバの値は不定です。



どなたか、部分的な自動構造化と自動配列初期化に関して、CとC++の標準が何を言っているか教えていただけませんか?私はVisual Studioで問題なく上記のコードを実行しますが、私はgcc/g++、そして多分他のコンパイラーとも互換性があるようにしたいです。ありがとうございます。

どのように解決するのですか?

リンクされたgccのドキュメントには 部分的な初期化 について述べているだけです。 (完全)初期化 あるいは 初期化なし .

パーシャル初期化とは何ですか?

標準規格では、オブジェクトの部分的な初期化は定義されていません。部分的な初期化とは、一般的に、いくつかの初期化子を提供するが、すべてではない状況、つまり、初期化される配列のサイズまたは構造要素の数よりも少ない初期化子を提供する状況を指す、非標準の用語です。

int array[10] = {1,2};                    //Case 1:Partial Initialization

(完全)初期化、初期化なしとは何ですか?

初期化とは、変数が作成されるときに、同時に作成される変数に何らかの初期値を与えることです。

int array[10] = {0,1,2,3,4,5,6,7,8,9};    //Case 2:Complete Initialization
int array[10];                            //Case 3:No Initialization

引用したパラグラフでは Case 3 .

部分的な初期化に関するルール( Case 1 )に関するルールは標準によってよく定義されており、これらのルールは初期化される変数の保存型に依存しません。

AFAIKは、すべての主流のコンパイラーはこれらのルールに100%準拠しています。


どなたか、CとC++の標準が、部分自動構造化と自動配列初期化について、どのように言っているか教えてください。

CとC++の規格では、整数配列が自動記憶上にあり、中括弧で囲まれたリスト内の初期化子の数が初期化されていない要素の数より少ない場合でも でなければなりません。 に初期化されなければなりません。 0 .

C99 スタンダード 6.7.8.21

中括弧で囲まれたリスト内の初期化子の数が集約の要素又はメンバの数より少ない場合、又は既知のサイズの配列を初期化するために使用される文字列リテラルの文字数が配列内の要素の数より少ない場合、集約の残りは静的記憶期間を持つオブジェクトと同様に暗黙的に初期化されなければならない。


C++では、ルールは少しの違いで記載されています。

C++03 標準 8.5.1 集計値

パラ 7。

リスト内の初期化子が集合体内のメンバの数より少ない場合、明示的に初期化されていない各メンバは 値で初期化される (8.5). [例

 struct S { int a; char* b; int c; };
 S ss = { 1, "asdf" };

初期化 ss.a1 , ss.b"asdf" であり、かつ ss.c という形の式の値で int() である,ということである。 0 . ]

Value Initializationが定義されているのに対して

C++03 8.5 初期化子

パラ5。

への 値初期化 というのは、タイプTのオブジェクトを意味します。

- T がユーザが宣言したコンストラクタ (12.1) を持つクラス型 (第9節) である場合、T のデフォルトコンストラクタが呼ばれます (そして、T にアクセス可能な デフォルトコンストラクタがない場合、初期化は不正確です)。

- T がユーザー定義のコンストラクタを持たない非組合クラス型である場合、T のすべての非静的な データメンバ、および T のベースクラスコンポーネントは値で初期化されます。

- もしTが配列型であれば、各要素は値で初期化されます。

- そうでなければ、オブジェクトはゼロ初期化されます。