Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.

Public Report
Report From: Delphi-BCB/RTL/Delphi/WinAPI    [ Add a report in this area ]  
Report #:  115307   Status: Resolved
PDWORD is not defined as ^DWORD in Winapi.Windows.pas
Project:  Delphi Build #:  18.0.4854.59655
Version:    18.0 Submitted By:   Francois Piette (OverByte)
Report Type:  Basic functionality failure Date Reported:  4/28/2013 8:46:24 AM
Severity:    Serious / Highly visible problem Last Updated: 2/20/2015 5:28:43 PM
Platform:    All versions Internal Tracking #:   38908
Resolution: Checked In (Resolution Comments) Resolved in Build: : None
Duplicate of:  None
Voting and Rating
Overall Rating: (3 Total Ratings)
5.00 out of 5
Total Votes: 36
Description
Type declaration for PDWORD is wrong in Winapi.Windows unit.
There is even a comment about it:
[Winapi.Windows.pas]
-----
  ...
  // Note: Not ^DWORD yet
  PDWORD = ^CppULongInt;
  {$EXTERNALSYM PDWORD}
  LPDWORD = PDWORD;
  {$EXTERNALSYM LPDWORD}
  ...
-----

This break existing code with an error: " E2033 Types of actual and formal var parameters must be identical".

PDWORD are frequently used when importing function from DLL.

As an example see "Steps".
Steps to Reproduce:
Try to compile the following program:
---------
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}

uses
  Winapi.Windows, System.SysUtils;

procedure F(var A : DWORD);
begin
    // Nop
end;

var
  D : DWORD;
  P : PDWORD;
begin
  D := 4;
  P := @D;
  F(D);     // Works
  F(P^);    // E2033 Types of actual and formal var parameters must be identical
end.
---------
Workarounds
Use a type cast. In my example code, replace
    F(P^);
by
    F(DWORD(P^));
Attachment
None
Comments

Warren Postma at 4/16/2014 7:52:22 AM -
This deserves some documentation, or else, to be fixed properly.  It breaks working code that people try to port up to XE4,XE5, and XE6, code that apparently worked FINE up to XE2 and XE3 levels.

Luigi Sandon at 9/15/2014 12:08:57 AM -
IMHO, it's a bug. If you read http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx DWORD is explicitly defined as a *32* bit unsigned integer, and PDWORD as a pointer to it.

Thereby it should be defines as:

DWORD = Uint32;
PDWORD = ^DWORD;

It's DWORD_PTR to be defined as an ULONG_PTR, and ULONG_PTR is a 32 bit long pointer on 32 bit platform and a 64 bit long pointer on 64 bit ones.

If they made a different choice because of using DWORD on non Windows platforms with a different semantic, well, they did a big mistake because the definition is no longer valid on Windows platforms.

Server Response from: ETNACODE01