Предупреждение. Небезопасный тип "TSmallPoint" для "Integer"

Я использую этот код в своем проекте:

var
  P: TPoint;

MyControl.Perform(WM_LBUTTONDOWN, 0, Longint(PointToSmallPoint(P)));

Компилятор дает мне предупреждение:

[Warning]: Unsafe typecast of 'TSmallPoint' to 'Integer'

Но тот же код используется в Controls.pas без каких-либо предупреждений - например, в методе TControl.BeginDrag:

....
Perform(WM_LBUTTONUP, 0, Longint(PointToSmallPoint(P)));

Я не вижу ни одного {$warnings off} в Controls.pas.

Почему компилятор предупреждает меня, но пропускает предупреждение для Controls.pas?
Этот код небезопасен?


Изменить: в моих настройках проекта → Сообщения компилятора → Небезопасный Typecast отмечен (который по умолчанию не отмечен).
Возможно, именно поэтому @David и @Ken не смогли воспроизвести предупреждение.

Ответ 1

Это вызвано тем, что у вас есть предупреждения unsafe typecast, отмеченные в Project- > Options- > Compiler Messages. Это безопасно для снятия отметки (как unsafe type и unsafe code над ним. (См. Ниже.)

Я не смог воспроизвести предупреждение, потому что у меня есть небезопасный тип, который не установлен. Это уже не применимо. (Он был добавлен в Delphi 6 или 7 для совместимости .net, когда они разрабатывали Delphi для .NET, чтобы упростить запись кода, который работал как для .NET, так и для Win32, поскольку продукт Delphi для .NET был прекращен, это предупреждение (и два выше) больше не применяются). "Небезопасно" в этих трех предупреждениях использует значение .NET "небезопасно", что означает "неуправляемый".

Из файла справки Delphi 7 (поиск "Изменения компилятора" ) (выделение внимания):

Компилятор Delphi dcc32 теперь поддерживает три дополнительных предупреждения компилятора: Unsafe_Type, Unsafe_Code и Unsafe_Cast. Эти предупреждения отключены по умолчанию, но могут быть включены с помощью директивы компилятора {$ WARN UNSAFE_CODE ON}, коммутатора командной строки компилятора (dcc32 -W + UNSAFE_CODE) и в IDE в проекте | Параметры | Страница сообщений компилятора.

Эта функция предназначена для передачи вашего кода в управляемую среду выполнения платформы Microsoft.NET. В управляемой среде исполнения "небезопасно" означает, что операция не может быть проверена во время статического анализа, выполняемого компилятором Just In Time (JIT). Такой код может представлять угрозу безопасности, поскольку информации для JIT, чтобы проверить его поведение во время выполнения. Примеры небезопасного кода включают операции указателя и перезапись памяти.

Ответ 2

Если вы сами скомпилируете блок Controls, при включенном предупреждении о небезопасном отображении, вы увидите предупреждение. Но если вы связали предварительно созданный файл .dcu, вы не увидите предупреждения. Компилятор только генерирует предупреждения на единицах, которые он компилирует.

Как правило, модули RTL и VCL генерируют большое количество подсказок и предупреждений. Если когда-либо мне придется перекомпилировать их, мне всегда нужно отключать подсказки и предупреждения на этих устройствах.


Современная документация для предупреждения говорит:

Вы использовали тип данных или операцию, для которых статический анализ кода не может доказать, что он не перезаписывает память. Например, у вас может быть одна (одна) запись в другую или один экземпляр на другой.

И это предупреждение распространяется на ваш код. Ваш код небезопасен. Компилятор не может проверить правильность наложения двух 16-битных целых чисел на 32-битное целое число. Поэтому компилятор предупреждает вас. Вам решать, правильно ли код.

Теперь, похоже, что предупреждение предназначалось в первую очередь для компилятора .net. Тем не менее, он все еще имеет смысл для компилятора Win32. Наложение одной записи на другую - это подозрительное поведение.