質問

私は 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 でこれに依存しても安全かどうか疑問に思っています。たとえば、コンパイラの設定に依存するのではないか、それともマシンごとに動作が異なるのではないかと考えています。オブジェクトのデフォルトの初期化値に依存するのが通常ですか、それともコンストラクターですべてのインスタンス変数を明示的に設定しますか?

スタック (プロシージャレベル) 変数に関しては、私のテストでは、初期化されていないブール値は true、初期化されていない整数は 2129993264、そして初期化されていないオブジェクトは単なる無効なポインターであることが示されています。ゼロではありません)。プロシージャレベルの変数にアクセスする前に、常にプロシージャレベルの変数を設定するのが標準だと思いますか?

役に立ちましたか?

解決

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

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

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

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

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

それを覚えてる バリー・ケリー どこかに「reference-counted」の定義が書かれていましたが、もう見つからないので、当面はこれで済むはずです。

参照カウント==それ自体が参照されるか、直接または間接的にフィールド(レコード用)または要素(配列用)が含まれています。 string, variant, interfaceまたは 動的配列 または 静的配列 このようなタイプが含まれています。

ノート:

  • record それ自体は参照カウントされるには十分ではありません
  • ジェネリック医薬品ではまだ試していません

他のヒント

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

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

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

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

var myGlobal:integer=99;

これは Ray Lischners Delphi からの引用です。 第2章

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

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

編集...Barry Kelly は、ゼロ初期化されていることを信頼できると言っています。彼は Delphi コンパイラ チームの一員なので、それは正しいと思います :) Barry に感謝します。

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

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

Delphi 2007 ヘルプ ファイルより:

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

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top