W1024组合有符号和无符号类型 - 扩展了两个操作数

时间:2015-04-03 10:16:11

标签: delphi

如何防止此警告? [DCC警告] uFvSystem.pas(293):W1024组合有符号和无符号类型 - 扩展了两个操作数

function LinkerTimestamp: TDateTime; overload;
begin
  Result := PImageNtHeaders(HInstance + PImageDosHeader(HInstance)^._lfanew)
   ^.FileHeader.TimeDateStamp / SecsPerDay + UnixDateDelta;
end;

2 个答案:

答案 0 :(得分:3)

错误消息表明您正在使用混合有符号和无符号操作数执行整数运算。这里唯一的整数运算是:

HInstance + PImageDosHeader(HInstance)^._lfanew

第一个操作数是无符号的,第二个操作数是有符号的,即使它必须是正数。

您可以使用强制转换来抑制警告。最好在无符号上下文中执行算法,以避免范围检查错误。因此,演员表被放置在第二个操作数周围:

HInstance + NativeUInt(PImageDosHeader(HInstance)^._lfanew)

HInstance + Cardinal(PImageDosHeader(HInstance)^._lfanew)

如果您的旧Delphi没有NativeUInt

但是,你实际上是在对指针进行算术运算,所以我会这样写:

PByte(HInstance) + PImageDosHeader(HInstance)^._lfanew

PAnsiChar(HInstance) + PImageDosHeader(HInstance)^._lfanew

在较旧的Delphi版本中PByte不支持算术运算。

答案 1 :(得分:0)

_lfanew字段为LongIntHInstance变量可能是THandle,它是Cardinal或某种等效类型的别名。有你签名和未签名的类型。

总和应该是什么类型的?可能值的范围比THandle的大小宽一位。 ( m 位数和 n 位数的总和最多需要max(m, n)位。)所涉及的类型都不够大,所以编译器将它们推广到更广泛的类型,以适应整个范围。

您对编译器没有的这些变量的范围有所了解。特别是,您知道_lfanew是以HInstance为基础的内存范围的偏移量。只要没有文件损坏,HInstance_lfanew的总和将是有效地址,因此您可以安全地将_lfanew类型转换为无符号类型确信总和不会溢出:

Result := PImageNtHeaders(HInstance + UIntPtr(PImageDosHeader(HInstance)^._lfanew))
  ^.FileHeader.TimeDateStamp / SecsPerDay + UnixDateDelta;

如果您的Delphi版本提供,请使用UIntPtr。否则,NativeUIntCardinal即可。