Эта программа
{$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;
Итак, CppULongInt
и DWORD
- разные типы. Следовательно, ошибка компиляции.
Что здесь происходит? Какова цель CppULongInt
? Почему разработчикам RTL требуется псевдоним DWORD
- CppULongInt
. Является ли это изменение связано с компилятором x64 Windows С++ на основе LLVM? Я единственный человек в мире, который использует {$TYPEDADDRESS ON}
?
Обратите внимание, что последний вопрос является риторическим.