web-dev-qa-db-ja.com

デルファイ変数はデフォルトで値で初期化されていますか?

私はDelphiが初めてで、デフォルトで初期化されるオブジェクト変数とスタック変数を確認するためにいくつかのテストを実行しています。

TInstanceVariables = class
  fBoolean: boolean; // always starts off as false
  fInteger: integer; // always starts off as zero
  fObject: TObject; // always starts off as nil
end;

これは私が他の言語から慣れている振る舞いですが、Delphiでそれを信頼しても安全かどうか疑問に思っていますか?たとえば、コンパイラの設定に依存するのか、それともマシンによって動作が異なるのか疑問に思っています。オブジェクトのデフォルトの初期化された値に依存するのは正常ですか、またはコンストラクターですべてのインスタンス変数を明示的に設定しますか?

スタック(手順レベル)変数に関しては、私のテストでは、初期化されたブール値が真であり、初期化された整数が2129993264であり、初期化されていないオブジェクトは無効なポインター(つまり、nilではない)であることを示しています。私は、それらにアクセスする前に常にプロシージャレベルの変数を常に設定するのが普通だと推測していますか?

98
MB.

はい、これは文書化された動作です:

  • オブジェクトフィールドは常に0、0.0、 ''、False、nil、または該当するものに初期化されます。

  • グローバル変数も常に0などに初期化されます。

  • ローカル参照カウント*変数は常にnilまたは ''に初期化されます。

  • 参照カウントされていないローカル変数は初期化されていないため、使用する前に値を割り当てる必要があります。

Barry Kelly が "reference-counted"の定義をどこかに書いたが、それを見つけることができなかったことを覚えているので、それまではそうすべきです:

reference-counted ==それ自体が参照カウントされるか、直接または間接的に参照カウントされるフィールド(レコード用)または要素(配列用)を含む:string, variant, interfaceまたはdynamic arrayまたはstaticタイプ

ノート:

  • record自体は、参照カウントになるのに十分ではありません
  • 私はまだジェネリックでこれを試していません
100

明示的な初期化子を持たないグローバル変数は、実行可能ファイルのBSSセクションに割り当てられます。実際には、EXE内のスペースを占有しません。 BSSセクションは、OSが割り当ててゼロにクリアする特別なセクションです。他のオペレーティングシステムでも、同様のメカニズムがあります。

グローバル変数がゼロで初期化されることに依存できます。

26
Barry Kelly

クラスフィールドはデフォルトではゼロです。これは文書化されているため、信頼することができます。ローカルスタック変数は、文字列またはインターフェイスがない限り定義されません。これらはゼロに設定されます。

20
Martin Liesén

念のために(Delphiを初めて使用する場合):グローバル変数は宣言時に直接初期化できます。

var myGlobal:integer=99;
16

レイ・リシュナーズDelphi in a Nutshell Chapter 2 からの引用です

「Delphiが最初にオブジェクトを作成すると、すべてのフィールドが空になります。つまり、ポインターはnilに初期化され、文字列と動的配列は空になり、数値の値は0になり、ブールフィールドはFalseになり、VariantはUnassignedに設定されます。 (詳細については、第5章のNewInstanceおよびInitInstanceを参照してください。)」

スコープ内のローカル変数を初期化する必要があるのは事実です...上記の「グローバル変数が初期化されている」というコメントは、参照が提供されるまで疑わしいものとして扱います。

編集...バリー・ケリーは、それらがゼロで初期化されることに頼ることができると言います、そして彼がDelphiコンパイラチームにいるので、私はそれが立っていると信じています:)ありがとうバリー。

8
Drew Gibson

グローバル変数とオブジェクトインスタンスデータ(フィールド)は常にゼロに初期化されます。プロシージャおよびメソッドのローカル変数は、Win32 Delphiでは初期化されません。コードで値を割り当てるまで、その内容は未定義です。

6
Ondrej Kelle

Delphi 2007ヘルプファイルから:

ms-help://borland.bds5/devcommon/variables_xml.html

「グローバル変数を明示的に初期化しない場合、コンパイラはそれを0に初期化します。」

4
Ondrej Kelle

言語がデフォルトの初期化を提供していても、それらに依存すべきだとは思わない。値への初期化により、言語のデフォルトの初期化を知らない他の開発者にとって、より明確になり、コンパイラー全体で問題を防ぐことができます。

4
Thomas Owens

与えられた答えには少し不満があります。 Delphiは、グローバルおよび新しく作成されたオブジェクトのメモリ空間をゼロにします。 [〜#〜] normally [〜#〜]は初期化されることを意味しますが、初期化されない場合が1つあります。特定の値を持つ列挙型です。ゼロが正当な値ではない場合はどうなりますか?

3
Loren Pechtel