INVALID_HANDLE_VALUE is not of THandle type on Linux

Summary

On Linux x86-64 INVALID_HANDLE_VALUE is DWORD(-1) but THandle = Longint;.

System Information

  • Operating system: Linux
  • Processor architecture: x86-64
  • Compiler version: trunk
  • Device: Computer

Steps to reproduce

Compare a THandle value with INVALID_HANDLE_VALUE and you get a "Warning: Comparison might be always true due to range of constant and expression".

Example Project

program InvalidHandleValue;

uses SysUtils;

var
  xFileHandle: THandle;
begin
  xFileHandle := FileOpen('test.txt', fmOpenRead or fmShareDenyWrite);
  if xFileHandle<>INVALID_HANDLE_VALUE then // InvalidHandleValue.lpr(9,17) Warning: Comparison might be always true due to range of constant and expression
  begin
    //
  end;
end.

What is the current bug behavior?

THandle is signed (-1) but INVALID_HANDLE_VALUE is unsigned, so the comparison is not executed correctly.

What is the expected (correct) behavior?

No warning, correct comparison.

Possible fixes

I suggest to declare INVALID_HANDLE_VALUE as:

{$IFNDEF HAS_INVALIDHANDLE}
const
  INVALID_HANDLE_VALUE = THandle(-1);
{$ENDIF}

Yes, I know, INVALID_HANDLE_VALUE will have different values on different OS, but that goes for e.g. sLineBreak as well.

Or if this is not wanted then do not declare INVALID_HANDLE_VALUE on Linux at all and keep it Windows only.

Documentation

See https://www.freepascal.org/docs-html/rtl/sysutils/fileopen.html : On Error, THandle(-1) is returned.

Edited by Ondrej Pokorny