Reputation: 2287
How can I prevent this warning? [DCC Warning] uFvSystem.pas(293): W1024 Combining signed and unsigned types - widened both operands
function LinkerTimestamp: TDateTime; overload;
begin
Result := PImageNtHeaders(HInstance + PImageDosHeader(HInstance)^._lfanew)
^.FileHeader.TimeDateStamp / SecsPerDay + UnixDateDelta;
end;
Upvotes: 2
Views: 2891
Reputation: 613222
The error message indicates that you are performing integer arithmetic with mixed signed and unsigned operands. The only integer arithmetic is here:
HInstance + PImageDosHeader(HInstance)^._lfanew
The first operand is unsigned, the second is signed, even though it must be positive.
You can suppress the warning with a cast. It is better to perform the arithmetic in an unsigned context and so avoid range check errors. Hence the cast is placed around the second operand:
HInstance + NativeUInt(PImageDosHeader(HInstance)^._lfanew)
or
HInstance + Cardinal(PImageDosHeader(HInstance)^._lfanew)
if you have an older Delphi that does not have NativeUInt
.
However, you are actually performing arithmetic on pointers and so I would write it like this:
PByte(HInstance) + PImageDosHeader(HInstance)^._lfanew
or
PAnsiChar(HInstance) + PImageDosHeader(HInstance)^._lfanew
in older Delphi versions for which PByte
does not support arithmetic.
Upvotes: 5
Reputation: 163317
The _lfanew
field is a LongInt
. The HInstance
variable is probably a THandle
, which is an alias for Cardinal
or some equivalent type. There are your signed and unsigned types.
What type should the sum have? The range of possible values is one bit wider than the size of THandle
. (The sum of an m-bit number and an n-bit number needs at most max(m, n)
bits.) Neither of the types involved is big enough, so the compiler promotes them both to a wider type that will accommodate the full range.
You know something about the ranges of these variables that the compiler doesn't. In particular, you know that _lfanew
is an offset into a range of memory that has HInstance
as its base. As long as there's no file corruption, the sum of HInstance
and _lfanew
will be a valid address, so you can safely type-cast _lfanew
to an unsigned type with the confidence that the sum won't overflow:
Result := PImageNtHeaders(HInstance + UIntPtr(PImageDosHeader(HInstance)^._lfanew))
^.FileHeader.TimeDateStamp / SecsPerDay + UnixDateDelta;
Use UIntPtr
if your version of Delphi offers it. Otherwise, NativeUInt
or Cardinal
will do.
Upvotes: 0