通过IDE(F9)运行以下代码示例会得到混合结果
var objTemp : TMemDataSet; begin if (objTemp = nil) then ShowMessage('Nil'); end;
> 32位/调试模式,默认为零
> 32位/释放模式,默认为零
> 64位/调试模式,默认为零
> 64位/释放模式,默认为零
我的理解是值应始终默认为零.
还在XE2和XE5下对此进行了测试,结果相同.
这是Delphi中的预期行为吗?
解决方法
从XE5 documentation开始(参见“声明变量”部分的底部 – 我在Wiin32中包含了类型拼写错误,但重点是我的):
If you don’t explicitly initialize a global variable,the compiler
initializes it to 0. Object instance data (fields) are also
initialized to 0. On the Win32 platform,the contents of a local
variable are undefined until a value is assigned to them.Note that whenever Emba writes “Win32” they mean non-ARC compiler,so the above is also valid for Win64 and OSX.
您可以在帮助索引中使用搜索词Variables在Delphi 2007中找到相同的信息;它是“变量VBScript”和“变量[OpenGL]”之间的一个.
您在Win64调试版本中看到的差异可能只是编译器完成的事情,幸运事故或完全不同的事情.不过,这应该不重要.如您所知,默认情况下不会初始化局部变量,只需确保在使用它们之前在所有情况下都这样做.执行并不困难;当你声明一个局部变量时
var MyObj: TSomething;
你自己分配一个值,或者你从代码中的其他地方收到的东西:
MyObj := TSomething.Create; // Created yourself MyObj := GetSomething(); // Function result MyObj := Self.SomethingCollection[Self.SomethingCount - 1]; // Local ref
绝对没有理由需要依赖于初始化的局部变量,因为测试可以在分配给本地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');