78

たとえば、somestruct3つの整数メンバーがある場合、C(またはC ++)関数でこれを実行しても問題ないと常に考えていました。

somestruct s = {123,};

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


最近、GNUCリファレンスマニュアルで次のことを読みました。

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


部分的な自動構造と自動配列初期化に関して、CおよびC ++標準が何を言っているか教えてもらえますか?上記のコードはVisualStudioで問題なく実行できますが、gcc / g ++と互換性があり、他のコンパイラーとも互換性があります。ありがとう

4

3 に答える 3

112

リンクされた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

Partial Initialization(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.aます。]1ss.b"asdf"ss.cint()0

値の初期化はで定義されていますが、
C ++ 03 8.5初期化子
パラ5:

タイプTのオブジェクトを値初期化
するということは、次のことを意味します 。— Tがユーザー宣言コンストラクター(12.1)を持つクラスタイプ(9節)の場合、Tのデフォルトコンストラクターが呼び出されます(Tの場合、初期化は不正な形式になります)アクセス可能なデフォルトコンストラクタはありません);
— Tがユーザー宣言コンストラクターのない非ユニオンクラスタイプである場合、Tのすべての非静的データメンバーと基本クラスコンポーネントは値で初期化されます。
— Tが配列型の場合、各要素は値で初期化されます。
—それ以外の場合、オブジェクトはゼロで初期化されます

于 2012-05-31T06:13:35.253 に答える
18

Cでは、オブジェクトが部分的に初期化されることはありません。オブジェクトの一部が初期化されると、オブジェクト全体(およびすべてのサブオブジェクトが再帰的に)が初期化されます。明示的なイニシャライザーが指定されていない場合、要素は「適切なタイプのゼロ」に初期化されます。

あなたの質問の引用は、サブオブジェクトに初期化子がない場合ではなく、オブジェクト全体の初期化子が完全に省略されている場合を指します。たとえば、arrに自動保存期間があるとすると、次のようになります。

int arr[100] = { 123 };

arr[0]to123およびtoの他のすべての要素を初期化arr0ます。これに対して:

int arr[100];

のすべての要素を初期化せずに残しますarr。引用が参照しているのはこの後者の場合です。

于 2012-05-31T06:31:18.643 に答える
5

最新のgccバージョンでは、「部分的に」初期化とzeromemを同時に行うこともできます。

typedef struct{
  int a,b,c;
}T;

T s = {0, .b=5};

構造体メンバーは次の値になります。a=0, b=5, c=0

他のコンパイラがこれを許可するかどうかについての情報はありません:p

于 2013-02-26T19:44:34.673 に答える