Uli*_*rdt 8 delphi overload-resolution delphi-xe2
在将一些代码从D2007移植到XE2时,我遇到了编译错误,我无法理解.请参阅以下示例:
procedure TForm1.FormPaint(Sender: TObject);
var
c: Char;
pc: PChar;
r: TRect;
begin
c := '1';
pc := @c;
r := Bounds(100, 100, 100, 100);
DrawText(Canvas.Handle, pc, 1, r, DT_SINGLELINE or DT_NOCLIP); //1
{$TYPEDADDRESS OFF}
DrawText(Canvas.Handle, @c, 1, r, DT_SINGLELINE or DT_NOCLIP); //2
{$TYPEDADDRESS ON}
DrawText(Canvas.Handle, @c, 1, r, DT_SINGLELINE or DT_NOCLIP); //3
DrawText(Canvas.Handle, PChar(@c), 1, r, DT_SINGLELINE or DT_NOCLIP); //4
end;
Run Code Online (Sandbox Code Playgroud)
D2007编译没有问题.的XE2编译器将拒绝标注的线//3与
[DCC Fehler] Unit1.pas(38):E2010 Inkompatible Typen:'string'和'Pointer'
我想这是由于新添加的DrawText重载接受Delphi字符串.
你能解释一下这个错误吗?这不是什么大问题,因为我有一个解决方法(显式铸造),但我很好奇.这个错误在后来的Delphi版本中是否仍然存在?
编辑:我问的是编译器中是否有错误,而不是解释为什么它存在.很可能我忽略了编译器拒绝我的代码的正当理由.
这似乎不是正常的重载解决情况. DrawText被定义为两次:
function DrawText(hDC: HDC;
lpString: PWideChar;
nCount: Integer;
var lpRect: TRect;
uFormat: UINT): Integer; external user32 name 'DrawTextW';
function DrawText(hDC: HDC;
const lpString: UnicodeString;
nCount: Integer;
var lpRect: TRect; uFormat: UINT): Integer;
begin
Result := Winapi.Windows.DrawText(hDC,
PWideChar(lpString),
nCount,
lpRect,
uFormat);
end;
Run Code Online (Sandbox Code Playgroud)
随着{$TYPEDADDRESS OFF}似乎一个^Char由编译器解释为一个无类型pointer是从来没有与一个声明的类型的兼容PChar,同时@c似乎解析为PCharOK.这似乎与{$TYPEDADDRESS OFF}旨在使所有指针类型无关的概念不一致.看来,PChar和^Char编译器比其他指针都莫名其妙地区别对待.
随着{$TYPEDADDRESS ON}双方@c并^Char成为相当,但只要没有重载理清好奇地被接受作为参数.
在这两种情况下,似乎在完全建立类型兼容性之前完成了重载决策.我不确定我会把它称为一个错误,但是......似乎行为在不引起问题的情况下变得棘手.
SSCCE
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
{$DEFINE OVLD}
{$IFDEF OVLD}
procedure Test(s:string); overload;
begin
end;
{$ENDIF}
procedure Test(x:PChar); {$IFDEF OVLD}overload; {$ENDIF}
begin
end;
var
c : Char;
pc : ^Char;
begin
{$TYPEDADDRESS OFF}
Test(@c);
Test(pc); //OVLD - Incompatible types : 'string'-'pointer'
//No OVLD - Incompat. types : 'PWideChar'-'pointer'
{$TYPEDADDRESS ON}
Test(@c); //OVLD - Incompatible types : 'string'-'pointer'
//No OVLD - OK
Test(pc); //OVLD - Incompatible types : 'string'-'pointer'
//No OVLD - OK
end.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
286 次 |
| 最近记录: |