这个节目
{$APPTYPE CONSOLE}
{$TYPEDADDRESS ON}
uses
Winapi.Windows;
procedure Foo(P: PDWORD);
begin
end;
procedure Bar;
var
dw: DWORD;
begin
Foo(@dw);
end;
begin
end.
在 XE3 中编译,但在 XE4、XE5、XE6 和 XE7 中不编译。错误位于
Foo(@dw);
[dcc32 Error] E2010 Incompatible types: 'PDWORD' and 'Pointer'
这感觉很奇怪。因此,经过一番挖掘后,问题似乎归结为PDWORD
。人们可能很自然地认为它会是:
PDWORD = ^DWORD;
XE3 中确实就是这种情况。在后来的版本中我们发现:
// Note: Not ^DWORD yet
PDWORD = ^CppULongInt;
奇怪的。那么,什么是CppULongInt
?
CppULongInt = type LongWord;
{$EXTERNALSYM CppULongInt 'unsigned long'}
{$OBJTYPENAME CppULongInt 'Bul' 'Gm'}
然后查看声明DWORD
我们发现:
//NOTE: DWORD should really be CppULongInt
DWORD = LongWord;
So, CppULongInt
and DWORD
是不同的类型。因此出现编译错误。
这里发生了什么?目的是什么CppULongInt
?为什么 RTL 设计者似乎想要别名DWORD
to CppULongInt
。此更改与基于 LLVM 的 x64 Windows C++ 编译器有关吗?我是世界上唯一使用的人吗{$TYPEDADDRESS ON}
?
请注意,最后一个问题是反问句。