问题描述
所以我总是听说类字段(基于堆)被初始化,但是基于堆栈的变量没有被初始化。我也听说记录成员(也是基于堆栈)也没有被初始化。编译器警告局部变量未初始化([DCC警告] W1036变量'x'可能未初始化),但不会对记录成员发出警告。所以我决定进行测试。
So I always heard that class fields (heap based) were initialized, but stack based variables were not. I also heard that record members (also being stack based) were also not initialized. The compiler warns that local variables are not initialized ([DCC Warning] W1036 Variable 'x' might not have been initialized), but does not warn for record members. So I decided to run a test.
我总是从整数和 false 从 Booleans 为所有记录成员。
I always get 0 from Integers and false from Booleans for all record members.
我尝试转动各种编译器选项(调试,优化等)开启和关闭,但没有任何区别。我的所有记录成员正在初始化。
I tried turning various compiler options (debugging, optimizations, etc.) on and off, but there was no difference. All my record members are being initialized.
我缺少什么?我在德尔福2009年更新2。
What am I missing? I am on Delphi 2009 Update 2.
program TestInitialization;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TR = Record
Public
i1, i2, i3, i4, i5: Integer;
a: array[0..10] of Integer;
b1, b2, b3, b4, b5: Boolean;
s: String;
End;
var
r: TR;
x: Integer;
begin
try
WriteLn('Testing record. . . .');
WriteLn('i1 ',R.i1);
WriteLn('i2 ',R.i2);
WriteLn('i3 ',R.i3);
WriteLn('i4 ',R.i4);
WriteLn('i5 ',R.i5);
Writeln('S ',R.s);
Writeln('Booleans: ', R.b1, ' ', R.b2, ' ', R.b3, ' ', R.b4, ' ', R.b5);
Writeln('Array ');
for x := 0 to 10 do
Write(R.a[x], ' ');
WriteLn;
WriteLn('Done . . . .');
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
ReadLn;
end.
输出:
Testing record. . . .
i1 0
i2 0
i3 0
i4 0
i5 0
S
Booleans: FALSE FALSE FALSE FALSE FALSE
Array
0 0 0 0 0 0 0 0 0 0 0
Done . . . .
推荐答案
全局变量为零初始化。在程序主程序的上下文中使用的变量可能是一个特殊情况;在程序的主要开始
有时它们被视为局部变量,特别是 -loop indexers的。但是,在您的示例中,
r
是一个全局变量,并从可执行文件的.bss部分分配,Windows加载器确保零填充。
Global variables are zero-initialized. Variables used in the context of the main
begin
..end
block of a program can be a special case; sometimes they are treated as local variables, particularly for
-loop indexers. However, in your example, r
is a global variable and allocated from the .bss section of the executable, which the Windows loader ensures is zero-filled.
局部变量被初始化,就像将它们传递给
Initialize
例程一样。 Initialize
例程使用运行时类型信息(RTTI)来清零字段(递归地 - 如果字段是数组或记录类型)和数组(递归 - 如果元素类型是一个托管类型的数组或记录),托管类型是以下之一:
Local variables are initialized as if they were passed to the
Initialize
routine. The Initialize
routine uses runtime type-info (RTTI) to zero-out fields (recursively - if a field is of an array or record type) and arrays (recursively - if the element type is an array or a record) of a managed type, where a managed type is one of:
- AnsiString
- UnicodeString
- WideString
- 界面类型(包括方法引用)
- 动态数组类型
- 变体
AnsiString
UnicodeString
WideString
an interface type (including method references)
dynamic array type
Variant
堆中的分配不一定要初始化;这取决于使用什么机制来分配内存。作为实例对象数据的一部分的分配由
TObject.InitInstance
填充。来自 AllocMem
的分配是零填充的,而 GetMem
分配不是零填充。初始化新
的分配将被初始化为初始化
。
Allocations from the heap are not necessarily initialized; it depends on what mechanism was used to allocate memory. Allocations as part of instance object data are zero-filled by
TObject.InitInstance
. Allocations from AllocMem
are zero-filled, while GetMem
allocations are not zero-filled. Allocations from New
are initialized as if they were passed to Initialize
.
这篇关于在Delphi中哪些变量被初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!