我是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)。我猜测规范是在访问它们之前始终设置过程级变量吗?
答案 0 :(得分:99)
是的,这是记录在案的行为:
对象字段始终初始化为0,0.0,'',False,nil或其他任何适用的字段。
全局变量也始终初始化为0等;
本地参考计数*变量始终初始化为nil或'';
本地非引用计数*变量未初始化,因此您必须先分配一个值才能使用它们。
我记得Barry Kelly某个地方为“引用计数”写了一个定义,但是找不到它,所以这应该在此期间做:
引用计数==自我引用计数,或 直接或间接包含字段(用于记录)或元素(用于 引用计数的数组:
string, variant, interface
或包含此类类型的动态数组或静态数组。
注意:
record
本身不足以成为引用计数答案 1 :(得分:26)
没有显式初始化程序的全局变量在可执行文件的BSS部分中分配。它们实际上并没有占用EXE中的任何空间; BSS部分是OS分配并清除为零的特殊部分。在其他操作系统上,有类似的机制。
您可以依赖零初始化的全局变量。
答案 2 :(得分:20)
类字段默认为零。这是记录在案的,所以你可以依赖它。 除非字符串或接口设置为零,否则本地堆栈可变量是未定义的。
答案 3 :(得分:16)
正如旁注(因为您是Delphi的新手):全局变量可以在声明时直接初始化:
var myGlobal:integer=99;
答案 4 :(得分:8)
以下是Ray Lischners Delphi在Nutshell Chapter 2
中的引用“当Delphi首次创建一个对象时,所有字段都是空的,也就是说,指针初始化为nil,字符串和动态数组为空,数字的值为零,布尔字段为False,并且设置了变量to Unassigned。(详见第5章中的NewInstance和InitInstance。)“
确实需要对本地范围内的变量进行初始化...我将上面的注释“全局变量初始化”视为可疑,直到提供参考 - 我不相信。
...编辑 Barry Kelly说你可以依赖它们进行零初始化,因为他在Delphi编译器团队中,我相信这就是:)感谢Barry。
答案 5 :(得分:6)
全局变量和对象实例数据(字段)始终初始化为零。 程序和方法中的局部变量未在Win32 Delphi中初始化;在代码中为它们分配值之前,它们的内容是未定义的。
答案 6 :(得分:4)
即使某种语言提供默认初始化,我也不相信你应该依赖它们。初始化为某个值会使其他开发人员更加清楚,这些开发人员可能不了解该语言中的默认初始化并防止编译器出现问题。
答案 7 :(得分:4)
来自Delphi 2007帮助文件:
MS-帮助://borland.bds5/devcommon/variables_xml.html
“如果没有显式初始化全局变量,编译器会将其初始化为0。”
答案 8 :(得分:3)
我对答案给出了一点抱怨。 Delphi将全局变量和新创建的对象的内存空间清零。虽然这个 NORMALLY 意味着它们被初始化,但有一种情况它们不是:具有特定值的枚举类型。如果零不是合法值怎么办?
答案 9 :(得分:0)
新引入的(自Delphi 10.3起)内联变量使初始值的控制更加容易。
procedure TestInlineVariable;
begin
var index: Integer := 345;
ShowMessage(index.ToString);
end;