107

私は 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 ではない) であることが示されています。アクセスする前に常にプロシージャレベルの変数を設定するのが標準だと思いますか?

4

10 に答える 10

109

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

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

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

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

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

バリー・ケリーがどこかで「参照カウント」の定義を書いたことを覚えていますが、それ以上は見つからないので、当面は次のようにする必要があります。

reference-counted == それ自体が参照カウントされるか、次のような参照カウントされるフィールド (レコードの場合) または要素 (配列の場合) を直接的または間接的に含む:string, variant, interface またはそのような型を含む動的配列または静的配列

ノート:

  • recordそれ自体は、参照カウントになるには十分ではありません
  • 私はまだジェネリックでこれを試していません
于 2008-09-25T11:41:38.347 に答える
27

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

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

于 2008-09-25T15:58:33.033 に答える
21

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

于 2008-09-25T11:33:12.017 に答える
18

補足として(Delphi は初めてなので):グローバル変数は、宣言時に直接初期化できます。

var myGlobal:integer=99;
于 2009-01-30T13:30:56.060 に答える
7

これは、一言で言えば第2章のRayLischnersDelphiからの引用です。

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

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

編集...バリーケリーは、ゼロで初期化されていることに依存できると言っています。彼はDelphiコンパイラチームに所属しているので、それは正しいと思います:)バリーに感謝します。

于 2008-09-25T12:03:05.690 に答える
6

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

于 2008-09-25T11:42:22.900 に答える
5

言語がデフォルトの初期化を提供している場合でも、それらに依存するべきではないと思います。値に初期化すると、言語のデフォルトの初期化について知らない可能性のある他の開発者にとってより明確になり、コンパイラ間での問題が防止されます。

于 2008-09-25T11:57:51.303 に答える
4

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

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

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

于 2008-09-25T14:27:33.347 に答える
3

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

于 2008-09-25T14:46:04.767 に答える