为什么不将对象默认为nil?

Jef*_*ope 6 delphi

在Delphi中,从TObject下降的变量的记录行为是默认值nil.但是,我遇到的情况并非如此.

通过IDE(F9)运行以下代码示例会得到混合结果

var
  objTemp : TMemDataSet;
begin
  if (objTemp = nil) then
     ShowMessage('Nil');
end;
Run Code Online (Sandbox Code Playgroud)
  • 32位/调试模式,默认为零
  • 32位/释放模式,默认为零
  • 64位/调试模式,默认为nil
  • 64位/释放模式,默认为零

我的理解是值应始终默认为零.

还在XE2和XE5下对此进行了测试,结果相同.

这是Delphi中的预期行为吗?

Ken*_*ite 11

你的理解是不正确的.未初始化非托管类型(IOW,非引用计数类型)的局部变量.您必须先为它们分配值才能使用它们.

XE5文档(参见"声明变量"部分的底部 - 我在Wiin32中包含类型拼写错误,但重点是我的):

如果没有显式初始化全局变量,编译器会将其初始化为0.对象实例数据(字段)也初始化为0. 在Win32平台上,局部变量的内容是未定义的,直到为它们赋值为止.

请注意,每当Emba写"Win32"时,它们意味着非ARC编译器,因此上述内容对Win64和OSX也有效.

您可以在帮助索引中使用搜索词Variables在Delphi 2007中找到相同的信息; 它是"变量VBScript"和"变量[OpenGL]"之间的一个.

您在Win64调试版本中看到的差异可能只是编译器完成的事情,幸运事故或完全不同的事情.不过,这应该不重要.如您所知,默认情况下不会初始化局部变量,只需确保在使用它们之前在所有情况下都这样做.执行并不困难; 当你声明一个局部变量时

var
  MyObj: TSomething;
Run Code Online (Sandbox Code Playgroud)

你自己分配一个值,或者你从代码中的其他地方收到的东西:

MyObj := TSomething.Create;   // Created yourself
MyObj := GetSomething();      // Function result
MyObj := Self.SomethingCollection[Self.SomethingCount - 1]; // Local ref
Run Code Online (Sandbox Code Playgroud)

绝对没有理由需要依赖于初始化的局部变量,因为测试可以在分配给本地var之前在外部引用上完成,或者在分配外部引用之后在本地var上完成:

if SomethingIGot = nil then
  raise Exception.Create('Received a nil parameter');
MyObj := SomethingIGot;

// or

MyObj := SomethingIGot;
if not Assigned(MyObj) then
  raise Exception.Create('MyObj was assigned a nil value');
Run Code Online (Sandbox Code Playgroud)