警告:'TSmallPoint'到'Integer'的不安全类型转换

时间:2012-12-28 22:47:43

标签: delphi delphi-7

我在我的项目中使用此代码:

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无法重现警告的原因。

2 个答案:

答案 0 :(得分:11)

这是因为您在Project->选项 - >编译器消息中检查了unsafe typecast警告。取消选中是安全的(如unsafe typeunsafe code一样。(见下文。)

我无法重现警告,因为我已取消选中不安全的类型转换。它已不再适用。 (当他们开发Delphi for .NET时,它在Delphi 6或7中添加了.net兼容性,以便更容易编写适用于.NET和Win32的代码;因为Delphi for .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编译器验证其运行时行为。不安全代码的示例包括指针操作和内存覆盖。

答案 1 :(得分:5)

如果您自己编译控制单元,并启用了不安全的类型转换警告,那么您将看到警告。但是如果你链接预先构建的.dcu文件,那么你看不到任何警告。编译器仅对其编译的单元发出警告。

作为一般规则,RTL和VCL单元会生成大量提示和警告。如果我不得不重新编译它们,我总是要在这些单元上关闭提示和警告。


警告的现代documentation说:

  

您使用的数据类型或操作静态代码分析无法证明它不会覆盖内存。例如,您可能已将(原文如此)一条记录装入另一条记录或将一个实例装入另一条记录。

该警告确实适用于您的代码。您的代码不安全。编译器无法验证将两个16位整数叠加到32位整数上是否正确。所以编译器警告你。由您决定代码是否正确。

现在,警告似乎主要用于.net编译器。尽管如此,它仍然对Win32编译器有意义。将一条记录叠加在另一条记录上是可疑行为。