19 июля 2023

NativeInt в Delphi 12 стал "слабым" псевдонимом

    В работе с целочисленными типами у компилятора Delphi 12 произошло существенное изменение, которое повлияет на перегрузку процедур/функций и совместимость 32-х и 64-х битного кода. Речь идет о "плавающем" типе NativeInt (NativeUInt). В 32-х битном приложении он эквивалентен типу Integer, а в 64-х битном типу Int64. К тому же размер NativeInt эквивалентен размеру указателя в выбранной платформе (4 или 8).
    До Delphi 12 типы данных Integer, Int64 и NativeInt компилятор рассматривал как различные. Это позволяло писать с их использованием перегруженные процедуры и функции. В зависимости от разрядности платформы, NativeInt был "сильным" псевдонимом или Integer или Int64. Например, вот такой код отлично компилировался, если компилятор мог однозначно определить тип передаваемого в процедуру значения.
Перегруженные процедуры в Delphi
Так как у меня здесь 32-битное приложение, то компилятор в 31-й строке понимает, что 2147483648 – это Int64. Замена вызова doIt(2147483648) на doIt(2147483647) или выбор 64-х битной платформы приведет к ошибке во время компиляции "E2251 Ambiguous overloaded call to 'doIt'".
Ошибка компилятора Delphi: E2251 Ambiguous overloaded call to 'doIt'
    В Delphi 12 тип NativeInt стал "слабым" псевдонимом. Его можно будет использовать вместо Integer или Int64, но не параллельно. Третий вариант процедуры doIt(I: NativeInt) приведет компилятор Delphi 12 к ошибке "E2004 Identifier redeclared: 'doIt'". У программиста остается выбор: или написать одну процедуру с использованием NativeInt:
procedure doIt(I: NativeInt);
или, если есть желание различать поведение при обработке 32-х и 64-х битных целых чисел, то делать две процедуры:
procedure doIt(I: Integer); overload;
procedure doIt(I: Int64); overload;

2 комментария:

  1. Все эти числовые типы DWORD, LARGE_INTEGER, DWORD64, DWORD_PTR и т.д. - НЕ родные типы данные языка. Они нужны для совместимости с портируемым кодом из других языков. Если вы создаете и поддерживаете нативный Delphi-проект, ВСЕГДА используйте только РОДНЫЕ типы данных.

    ОтветитьУдалить
  2. Анонимный02 марта, 2024 22:39

    А я думаю, почему старая библиотека не компилируется - ругается на дублирование функции. А там одна функция с NativeInt, а вторая Integer

    ОтветитьУдалить