kludg
kludg

Reputation: 27493

FPC 3.0 and InterlockedCompareExchange

I installed Lazarus 1.6/FPC 3.0, 64 bits on Windows 10 (64 bits) and porting Delphi code containing InterlockedCompareExchangePointer function.

FPC 3.0 does not include InterlockedCompareExchangePointer declaration; instead it "overloads" InterlockedCompareExchange as can be seen in systemh.inc:

function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint; public name 'FPC_INTERLOCKEDCOMPAREEXCHANGE';
{$ifdef cpu64}
function InterlockedCompareExchange64(var Target: int64; NewValue: int64; Comperand: int64): int64; public name 'FPC_INTERLOCKEDCOMPAREEXCHANGE64';
function InterlockedCompareExchange(var Target: Pointer; NewValue: Pointer; Comperand: Pointer): Pointer; external name 'FPC_INTERLOCKEDCOMPAREEXCHANGE64';
{$else cpu64}
function InterlockedCompareExchange(var Target: Pointer; NewValue: Pointer; Comperand: Pointer): Pointer; external name 'FPC_INTERLOCKEDCOMPAREEXCHANGE';
{$endif cpu64}

Now I am trying to use InterlockedCompareExchange with pointers:

program Project1;

uses Windows;

function Test: Boolean;
var
  P1, P2: Pointer;

begin
  Result:= InterlockedCompareExchange(P1, P2, nil) <> nil
end;

begin
  Test;
end.

and it does not compile with the message

project1.lpr(10,50) Error: Incompatible type for arg no. 3: Got "Pointer", expected "LongInt"

so evidently the "overload" does not work. How to fix it?

I am using 64-bit FPC 3.0 on default (64-bit) target.

Upvotes: 1

Views: 405

Answers (2)

HNB
HNB

Reputation: 337

InterlockedCompareExchangePointer added in FPC 3.1.1 (r34599) :

http://bugs.freepascal.org/view.php?id=29965

Upvotes: 0

kludg
kludg

Reputation: 27493

The following workaround

{$ifdef fpc}
function InterlockedCompareExchangePointer(var Target: Pointer; NewValue: Pointer; Comperand: Pointer): Pointer;
begin
{$ifdef cpu64}
  Result:= Pointer(InterlockedCompareExchange64(int64(Target), int64(NewValue), int64(Comperand)));
{$else cpu64}
  Result:= Pointer(InterlockedCompareExchange(LongInt(Target), LongInt(NewValue), LongInt(Comperand)));
{$endif cpu64}
end;
{$endif fpc}

compiles and ensures Delphi/FPC compatibility; looks like the absence of InterlockedCompareExchangePointer declaration is FPC bug that should be fixed.

Upvotes: 2

Related Questions