Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/Compiler/Delphi/Errors - Warnings    [ Add a report in this area ]  
Report #:  106911   Status: Open
Ord(boolean) leads to "unsigned" warning on compilation
Project:  Delphi Build #:  16.0.4504.48759
Version:    16.4 Submitted By:   Dmitry Burov
Report Type:  Basic functionality failure Date Reported:  7/5/2012 2:08:09 AM
Severity:    Commonly encountered problem Last Updated: 7/9/2012 1:12:12 AM
Platform:    All platforms Internal Tracking #:   29750
Resolution: None (Resolution Comments) Resolved in Build: : None
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: None
Description
procedure TGuideMainForm.ImChangeDefault(var M: TMessage);
begin
...
  btnOK.Default := (M.WParam <> Ord(False));
end;

[DCC Warning] GuideMainForms.pas(433): W1023 Comparing signed and unsigned types - widened both operands


The code is comparing two unsigned integers.
A 8bit unsigned integer with a 32bit unsigned integer.

What the lies does the warning say then ?
There is NO any signed integer, there is NO any reason to widen the numbers.

It was told that is is error in documentation.
It is not. Maybe documentation is incorrect here.
So let that hijacked issue 106502 remains that way, if you need and issue for documentation.

But my concern is not documentation. It is the error in the compiler.

The compiler, not the documentation, does issue incorrect warning and also probably does issue incorrect  (redundant and slow) code!

Common sense tells us that type should be unsigned type with sizeof() matching parameter
   ord (boolean) -> byte
   ord (WordBool) -> word
   ord (LongBool) -> cardinal
If not so, then probably should have map table in documentation, but anyway, having signed Ord result just makes no sense to me. No matter what do u map Ord to - it is unsigned by its nature and never can return negative numbers.
Steps to Reproduce:
procedure TGuideMainForm.ImChangeDefault(var M: TMessage);
begin
...
  btnOK.Default := (M.WParam <> Ord(False));
end;

[DCC Warning] GuideMainForms.pas(433): W1023 Comparing signed and unsigned types - widened both operands


source\rtl\win\Winapi.Messages.pas
  ->   TMessage = record
    Msg: Cardinal;
    case Integer of
      0: (
        WParam: WPARAM;

source\rtl\win\Winapi.Windows.pas
  ->    WPARAM = UINT_PTR;
  UINT_PTR = System.UIntPtr;  // NativeUInt;


In Delphi 5 definitely that was not an issue.

http://docwiki.embarcadero.com/Libraries/en/System.UIntPtr

This type is probably introduced with XE2 for 64-bit compatibility.

In BDS 2006 type WPARAM = Longint and that warning could make sense.
So directly chacking that code is not possible - there it really would be signed type on the left.

However i made that snippet for BDS 2006

function  CheckOrd : boolean;
var
  V: integer;
  U: cardinal;
begin
  Result := False;

  U := 1; V := 2;

  If U <> Ord(Result) then ;
  If V <> Ord(Result) then ;
  If U <> Ord(False) then ;
  If V <> Ord(False) then ;
  If U <> Ord(True) then ;
  If V <> Ord(True) then ;
exit;

Consistently every comparision with U generates the same warning.

So it is probably not the news in XE2. But it just surfaced beacuse of RTL changed TMessage type definition.

I would want to stress two faces of this issue.

1) to make Ord return a signed integer is just a nonsense.There is no semantical sense behind this.
2) constants like Ord(true) should be calculated during compilation and then "+1" constant can never be negative.

Also comparing Int32 unsigned and Int8 signed might be done via extending them to Int64 signed. But it is somehow dumb way to check for equality...
Workarounds
None
Attachment
None
Comments

Tomohiro Takahashi at 7/5/2012 7:26:32 AM -
Is this a regression in Delphi XE2?
What about previous versions of Delphi?

Dmitry Burov at 7/6/2012 6:02:38 AM -
http://docwiki.embarcadero.com/Libraries/en/System.UIntPtr

This type is probably introduced with XE2 for 64-bit compatibility.

In BDS 2006 type WPARAM = Longint and that warning could make sense.
So directly chacking that code is not possible - there it really would be signed type on the left.

However i made that snippet for BDS 2006


function  CheckOrd : boolean;
var
  V: integer;
  U: cardinal;
begin
  Result := False;

  U := 1; V := 2;

  If U <> Ord(Result) then ;
  If V <> Ord(Result) then ;
  If U <> Ord(False) then ;
  If V <> Ord(False) then ;
  If U <> Ord(True) then ;
  If V <> Ord(True) then ;
exit;

Consistently every comparision with U generates the same warning.

So it is probably not the news in XE2. But it just surfaced beacuse of RTL changed TMessage type definition.

I would want to stress two faces of this issue.

1) to make Ord return a signed integer is just a nonsense.There is no semantical sense behind this.
2) constants like Ord(true) should be calculated during compilation and then "+1" constant can never be negative.

Also comparing Int32 unsigned and Int8 signed might be done via extending them to Int64 signed. But it is somehow dumb way to check for equality...

Dmitry Burov at 7/6/2012 5:38:51 AM -
in Delphi 5 definitely that was not an issue :-)

Tomohiro Takahashi at 7/9/2012 2:47:02 AM -
This report was opened with valid Internal Tracking Number.
Thanks.

Server Response from: ETNACODE01