Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I use this code in my project:

var
  P: TPoint;

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

The compiler gives me a warning:

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

But, the same code is used in Controls.pas without any warnings - for example in TControl.BeginDrag method:

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

I don't see any {$warnings off} in Controls.pas unit.

Why is the compiler warning me, but skips the warning for Controls.pas?
Is this code Unsafe?


Edit: in my Project Options -> Compiler Messages -> Unsafe Typecast is checked (which by default is unchecked).
Maybe this is why @David and @Ken could not reproduce the warning.

like image 833
Vlad Avatar asked Dec 28 '12 22:12

Vlad


2 Answers

This is caused because you have unsafe typecast warnings checked in Project->Options->Compiler Messages. This is safe to uncheck (as are unsafe type and unsafe code above it. (See below.)

I couldn't reproduce the warning because I have unsafe type cast unchecked. It's no longer applicable. (It was added in Delphi 6 or 7 for .net compatibility when they were developing Delphi for .NET, to make it easier to write code that worked for both .NET and Win32; since the Delphi for .NET product was discontinued, that warning (and the two above it) are not applicable any longer). The "unsafe" in these three warnings use the .NET meaning of "unsafe", meaning "unmanaged".

From the Delphi 7 help file (search for "Compiler Changes") (emphasis mine):

The Delphi dcc32 compiler now supports three additional compiler warnings: Unsafe_Type, Unsafe_Code, and Unsafe_Cast. These warnings are disabled by default, but can be enabled with the compiler directive {$WARN UNSAFE_CODE ON}, compiler command line switch (dcc32 -W+UNSAFE_CODE), and, in the IDE, on the Project|Options|Compiler Messages page.

This feature is intended to help you port your code to the managed execution environment of Microsoft's .NET platform. In a managed execution environment, "unsafe" means the operation cannot be verified during the static analysis performed by the Just In Time (JIT) compiler. Such code might pose a security risk, since there is not enough information for the JIT compiler to verify its runtime behavior. Examples of unsafe code include pointer operations and memory overwrites.

like image 200
Ken White Avatar answered Nov 09 '22 14:11

Ken White


If you compile the Controls unit yourself, with the unsafe typecast warning enabled, then you will see the warning. But if you link the pre-built .dcu file then you see no warning. The compiler only emits warnings on units that it compiles.

As a general rule, the RTL and VCL units generate large numbers of hints and warnings. If ever I have to re-compile them, I always have to switch hints and warnings off on those units.


The modern day documentation for the warning says:

You have used a data type or operation for which static code analysis cannot prove that it does not overwrite memory. For example, you might have cased (sic) one record to another or one instance to another.

And that warning does apply to your code. Your code is unsafe. The compiler cannot verify that it is correct to overlay two 16 bit integers onto a 32 bit integer. So the compiler warns you. It's up to you to decide whether or not the code is correct.

Now, it appears that the warning was intended primarily for the .net compiler. All the same, it still has meaning for the Win32 compiler. Overlaying one record on another is suspicious behaviour.

like image 38
David Heffernan Avatar answered Nov 09 '22 12:11

David Heffernan