在Delphi中,从TObject下降的变量的记录行为是默认值nil.但是,我遇到的情况并非如此.
通过IDE(F9)运行以下代码示例会得到混合结果
var
objTemp : TMemDataSet;
begin
if (objTemp = nil) then
ShowMessage('Nil');
end;
Run Code Online (Sandbox Code Playgroud)
我的理解是值应始终默认为零.
还在XE2和XE5下对此进行了测试,结果相同.
这是Delphi中的预期行为吗?
综述:
请查看以下知识渊博的评论.
================================================== ============
我已经看到了managed types 很多stackoverflow Delphi主题中提到的术语.例如,它在主题中提到correctly initializing/finalizing.但是,当我谷歌时managed types,似乎大多数链接都与C++或.NET有关.例如,请参阅MSDN页面.有人可以帮助评论Delphi中定义的托管类型吗?鉴于Delphi for POSIX/MacOS正在诞生,是Windows特有的托管类型吗?感谢您提前付出的努力和时间!
PS:主题correctly initializing/finalizing:
在Delphi中初始化哪些变量?
delphi变量是否默认使用值初始化?
我应该如何在Delphi 7析构函数中释放一组对象?
在Delphi 2009中,我是否需要释放变体数组?
从优秀的Detour库中查看此演示源:
implementation
{$R *.dfm}
var
TrampolineGetMemory: function(Size: NativeInt): Pointer;
cdecl = nil;
Run Code Online (Sandbox Code Playgroud)
请看一下cdecl = nil;声明.在这种情况下它意味着什么?
注意 - 我已经知道它cdecl代表一个调用约定.
考虑这个简短的Delphi程序:
procedure TfrmXQuery.FieldListFillFromDefault;
var
field_list: TStringList;
begin
try
if x <> '' then begin
field_list := TStringList.Create;
{do some stuff with field_list}
end;
finally
if field_list <> NIL then
begin
field_list.Free;
end;
end;
end;
Run Code Online (Sandbox Code Playgroud)
当我在Delphi 3中运行它时,x =''以便永远不会创建field_list,
field_list <> NIL?NIL?NIL什么?NIL我怎么不知道Free它是否?该Assigned功能并没有告诉我:if Assigned(an_object)相当于if an_object = NILDelphi中的未初始化变量是否保证具有任何特定值
由于C++ Builder一般遵循Delphi的设计,因此C++ Builder中未初始化的变量保证具有任何特定的价值
我继承了一些C++ Builder代码,这些代码很大程度上取决于成员变量的零初始化,并试图弄清楚语言是否能保证这一点.
当Windows首次被提供给程序的堆栈或堆时,Windows是否保证内存是零初始化的?(编辑:我意识到程序会在执行时覆盖内存,所以它不能继续依赖于此;我只是想弄清楚我观察到的行为.)
我正在使用此代码来检查是否TStringList创建:
procedure TForm1.Button1Click(Sender: TObject);
var
sVariable : TStringList;
begin
if not Assigned(sVariable) then
sVariable:= TStringList.Create;
end;
Run Code Online (Sandbox Code Playgroud)
但条件False总是如此,为什么会发生这种情况?如何检查TStringList对象是否已创建?
Ps我知道有一个类似的问题问题,我试过在那个问题上发布的解决方案,但它对我不起作用.
我有这个功能:
var
_WordApplicationExistsCache: Integer = -1; // Cache result
function WordApplicationExists: Boolean;
var
WordObj: OleVariant;
begin
if (_WordApplicationExistsCache = -1) then
begin
Result := False;
try
try
WordObj := CreateOleObject('Word.Application');
WordObj.Visible := False;
WordObj.Quit;
WordObj := Unassigned;
Result := True;
except
// error
end;
finally
_WordApplicationExistsCache := Ord(Result); // 0;1
end;
end
else
begin
Result := Boolean(_WordApplicationExistsCache);
end;
end;
Run Code Online (Sandbox Code Playgroud)
我试图在应用程序生命周期中只调用一次此函数.我可能根本不会调用这个函数.
这是正确的模式吗?这可以做得更好吗?
编辑:我能想到的另一种方式,在这种情况下是使用2个变量:
var
_WordApplicationExistsInitialized: Boolean = False; // Cache result
_WordApplicationExistsCacheResult: Boolean; // Undefined ?
function WordApplicationExists: Boolean;
var
WordObj: …Run Code Online (Sandbox Code Playgroud) 在我的测试期间,以下情况始终会返回 True
var
Tmp : Boolean;
begin
if(Tmp)
then ShowMessage('True')
else ShowMessage('False');
end;
Run Code Online (Sandbox Code Playgroud)
编译时,我收到以下警告消息:
[DCC警告] Unit1.pas(30):W1036变量“ Tmp”可能尚未初始化
检查未分配的局部Boolean变量是否总是返回True还是纯属偶然?
我的公司使用Delphi已有数十年了,我们的核心程序是一个很旧的版本。它有大约130万行代码。
升级到Delphi 10 Rio后,出现了一个主要问题。我们的局部函数变量曾经使用默认值进行初始化(整数将为0,布尔值将为false),似乎不再是。现在我所有的变量在创建时都会获得一个随机值,因此整数的值类似于408796。
我想这不是新开发的问题,但是我相信您可以在我们的大型代码库中看到此问题。我们从来没有手动将默认值分配给这些变量,因为它可以正常工作。但是,对象变量始终存在此问题。所有属性均获得随机值,因此我们在进行处理时对此进行了改进。但是现在我们的程序完全中断了,因为所有计数器等都是从高值开始而不是从0开始。并且要遍历整个项目来解决这个问题,将需要几个月的时间。
也许有编译器选项可以更改此设置?倒退的是,他们会故意更改此设置,因为这样做很愚蠢。为什么要删除所有开发人员期望的功能?实际上,我原本希望这样做,否则对象变量将不再需要手动的默认值,并且可能实现了垃圾回收器。但是看来德尔福已经严重退步了吗?
如果有解决此问题的方法,请告诉我。
delphi ×9
delphi-7 ×2
variables ×2
c++builder ×1
default ×1
delphi-3 ×1
managed ×1
optimization ×1
tstringlist ×1
types ×1