下面是几个重载的函数。尝试猜测其中哪个函数会被调用。
program Project2;
{$APPTYPE CONSOLE}
uses
Types, SysUtils;
procedure Some(const Buf); overload;
begin
Writeln('const-typeless')
end;
//procedure Some(var Buf); overload;
// begin
// Writeln('var-typeless')
// end;
//procedure Some(Buf :TByteDynArray); overload;
// begin
// Writeln('Byte dynamic array');
// end;
procedure Some(Buf :array of Byte); overload;
begin
Writeln('Byte open array');
end;
procedure Some(Buf :TArray<Byte>); overload;
begin
Writeln('TBytes AKA byte generic array');
end;
//procedure Some(Buf :TBytes); overload;
// begin
// Writeln('TBytes AKA byte generic array');
// end;
var p: pointer;
begin
try
{ TODO -oUser -cConsole Main : Insert code here }
WriteLn ('Calling overloaded procedure with Pointer parameter:');
Write(' * nil: '); p := nil; Some(p);
Write(' * garbage: '); p := Pointer(1); Some(p);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
ReadLn;
end.
事实上,第二个被调用并在第二个调用时抛出 AV。鉴于旧的 VCL 模式使用Pointer
和Integer
可互换(例如TList
andTStrings.Objects
和TWinControl.Tag
)可能会在相当常规的代码上导致意外的 AV。
{$T+}不会改变行为,所以德尔福认为^Byte
不是Pointer.
但是声明p: PInteger;
修复它。开放数组变体也不需要指针,并且与泛型数组变体不同地处理/命名。动态数组的名称修改与通用数组不同,因此两者都可以使用,但如果两者都未注释,则在调用站点会发生模棱两可的重载错误。但是,如果在禁用通用数组和未注释动态数组的情况下进行编译 - 会发生同样的奇怪行为。
为什么编译器在参数为 a 时解析为动态/通用数组Pointer
,而在参数为时解析为无类型常量PInteger
?
- 相关:Delphi 如何解决带有整数参数的重载函数?
- 相关:为什么“字符串数组”的两个别名处理不同?
- 相关:QC 108978
- 代码来自:http ://www.sql.ru/forum/actualthread.aspx?tid=970289
PS。已开QC 109019