Recent

Author Topic: Why does FPC behave this way? Maybe we should create an issue?  (Read 2305 times)

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 417
  • I use FPC [main] 💪🐯💪
Why does FPC behave this way? Maybe we should create an issue?
« on: January 11, 2026, 06:55:22 am »
Code: Pascal  [Select][+][-]
  1. program app;
  2. {$mode objfpc}
  3.  
  4. var
  5.   p1: Pointer = nil;
  6.   p2: Pointer = nil;
  7.   r: NativeInt;
  8. begin
  9.   r := p2 - p1; // OK
  10.   r := p2 + p1; // Error
  11. end.

As far as I'm concerned, either option should be OK, or both options should be Error
I may seem rude - please don't take it personally

Thaddy

  • Hero Member
  • *****
  • Posts: 19165
  • Glad to be alive.
Re: Why does FPC behave this way? Maybe we should create an issue?
« Reply #1 on: January 11, 2026, 07:22:45 am »
Delphi does not accept this at all:
[dcc32 Error] Project11.dpr(9): E2015 Operator not applicable to this operand type
[dcc32 Error] Project11.dpr(10): E2015 Operator not applicable to this operand type
It looks a bug.
Also: pointers are unsigned by nature, but that does not matter here..
« Last Edit: January 11, 2026, 08:33:57 am by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

440bx

  • Hero Member
  • *****
  • Posts: 6491
Re: Why does FPC behave this way? Maybe we should create an issue?
« Reply #2 on: January 11, 2026, 09:37:04 am »
As far as I'm concerned, either option should be OK, or both options should be Error
No.  What FPC does in those cases is what should be done.

The difference between two pointers is the distance between the addresses something which is often needed.

The addition of two pointers is meaningless, therefore the compiler is right in rejecting the addition.  That said, if for some reason it would be needed to carry out such an operation, simply typecast the second pointer to ptruint and the compiler will then interpret it as a distance instead of a pointer thereby allowing the operation (I've never needed to add two pointers... ever!... the result is meaningless and quite likely totally useless... cannot think of an example, not even a contrived one, where it might be useful)

Conclusion: the compiler is right.  Subtraction is logically sound.  Addition is meaningless, therefore rejected.

« Last Edit: January 11, 2026, 09:39:41 am by 440bx »
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 19165
  • Glad to be alive.
Re: Why does FPC behave this way? Maybe we should create an issue?
« Reply #3 on: January 11, 2026, 09:51:50 am »
That leaves the small matter that Delphi does not accept both, although I think your reasoning is OK for mode objfpc.
objects are fine constructs. You can even initialize them with constructors.

440bx

  • Hero Member
  • *****
  • Posts: 6491
Re: Why does FPC behave this way? Maybe we should create an issue?
« Reply #4 on: January 11, 2026, 10:01:27 am »
That leaves the small matter that Delphi does not accept both, although I think your reasoning is OK for mode objfpc.
Delphi isn't always right (that said, it is much more often right than wrong.)

It's been a while since I used Delphi (Delphi 2 in my case) but, I remember taking the difference between two pointers in Delphi 2, what I don't remember is if I had to typecast the pointers for the operation to be allowed.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 417
  • I use FPC [main] 💪🐯💪
Re: Why does FPC behave this way? Maybe we should create an issue?
« Reply #5 on: January 11, 2026, 10:21:26 am »
Quote from: 440bx
...
Yes, that makes sense
I may seem rude - please don't take it personally

MarkMLl

  • Hero Member
  • *****
  • Posts: 8572
Re: Why does FPC behave this way? Maybe we should create an issue?
« Reply #6 on: January 11, 2026, 11:25:05 am »
That leaves the small matter that Delphi does not accept both, although I think your reasoning is OK for mode objfpc.

That could be explained if Delphi does not attempt to use "The Delphi Language" to write low-level memory management code.

I remember a 1970s book called something like "Writing Linkers and Loaders", the title of which would suggest that it was oriented towards mainframes. This made the argument that integers and pointers were a fairly close parallel to scalars and vectors in that there were permissible and illegal combinations: you can index relative to a pointer by adding or subtracting an integer, you can meaningfully subtract (but not add) and compare pointers for equality, you can't multiply pointers... and so on.

So while subtraction of pointers might be one of those operations best inaccessible to application-level programmers, it's definitely needed.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Thaddy

  • Hero Member
  • *****
  • Posts: 19165
  • Glad to be alive.
Re: Why does FPC behave this way? Maybe we should create an issue?
« Reply #7 on: January 11, 2026, 11:51:56 am »
I agree that the distance between raw pointers is useful indeed.
I guess that part is intentional.
objects are fine constructs. You can even initialize them with constructors.

simone

  • Hero Member
  • *****
  • Posts: 701
Re: Why does FPC behave this way? Maybe we should create an issue?
« Reply #8 on: January 11, 2026, 12:30:56 pm »
If I remember correctly, even in C, subtraction between pointers is allowed, but addition is not.
Microsoft Windows 10/11 64 bit - Lazarus 3.8/4.0 FPC 3.2.2 x86_64-win64-win32/win64

Thaddy

  • Hero Member
  • *****
  • Posts: 19165
  • Glad to be alive.
Re: Why does FPC behave this way? Maybe we should create an issue?
« Reply #9 on: January 11, 2026, 01:09:40 pm »
Just tested D7: same errors, both + and - not accepted by Delphi. My previous post was test with D12.1
objects are fine constructs. You can even initialize them with constructors.

440bx

  • Hero Member
  • *****
  • Posts: 6491
Re: Why does FPC behave this way? Maybe we should create an issue?
« Reply #10 on: January 11, 2026, 02:50:17 pm »
If I remember correctly, even in C, subtraction between pointers is allowed, but addition is not.
I remember successfully subtracting pointers in C.  I can't say anything about adding them because I've never needed that.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 19165
  • Glad to be alive.
Re: Why does FPC behave this way? Maybe we should create an issue?
« Reply #11 on: January 11, 2026, 03:30:01 pm »
C (any flavor) will not accept the addition without casts.
C will accept the difference without cast, like FPC does.
objects are fine constructs. You can even initialize them with constructors.

tetrastes

  • Hero Member
  • *****
  • Posts: 762
Re: Why does FPC behave this way? Maybe we should create an issue?
« Reply #12 on: January 12, 2026, 10:05:36 am »
I remember a 1970s book called something like "Writing Linkers and Loaders", the title of which would suggest that it was oriented towards mainframes. This made the argument that integers and pointers were a fairly close parallel to scalars and vectors in that there were permissible and illegal combinations: you can index relative to a pointer by adding or subtracting an integer, you can meaningfully subtract (but not add) and compare pointers for equality, you can't multiply pointers... and so on.

Fairly close parallel? For sure you can add and multiply vectors. ;D

Khrys

  • Sr. Member
  • ****
  • Posts: 439
Re: Why does FPC behave this way? Maybe we should create an issue?
« Reply #13 on: January 12, 2026, 11:59:46 am »
Fairly close parallel? For sure you can add and multiply vectors. ;D

Component-wise, scalar product or cross product?  ;)

In any case, has anyone tried this with typed pointers in Delphi?
It's important to note that e.g.  PByte(A) - PByte(B) <> PInteger(A) - PInteger(B),  which is required to uphold the indexing identity  Ptr[Index] = (Ptr+ Index)^  (i.e. pointee size must be taken into account).

Since  void*  is an incomplete type and thus has no well-defined size, pointer arithmetic on  void*  is forbidden in C and C++.  Maybe Delphi is just following suit?

440bx

  • Hero Member
  • *****
  • Posts: 6491
Re: Why does FPC behave this way? Maybe we should create an issue?
« Reply #14 on: January 12, 2026, 12:39:38 pm »
Actually, there is no good reason to disallow the subtraction of two plain/untyped pointers in Pascal.

A plain/untyped pointer is an address, the type it points to is unknown since it is untyped but, there is no doubt whatsoever that it is an address.   Subtracting two untyped addresses yields the number of memory units between those two addresses and, in today's computers, a memory unit is a byte. 

Therefore, the subtraction of two untyped pointers should yield the number of bytes between the two addresses.

The really important thing when subtracting pointers is that they MUST be of the same type, otherwise the subtraction is senseless. For instance, subtracting a pointer to a boolean from a pointer to a qword, makes no sense because the unit of distance between those pointers/addresses cannot be established.

In Pascal, an untyped pointer is the address of the minimum addressable memory unit, i.e, a byte, subtraction of such pointers should be allowed just as they are allowed on ^byte (since they are implicitly pointers to a byte.)

Note that in C, a void* is _not_ semantically identical to a Pascal untyped pointer because in C, there is the concept of a void item/object.  That does not exist in Pascal, i.e, there is no ^; (pointer to semicolon, which would be the Pascal "pointer to empty", overloading the semicolon to mean not only empty statement but "empty anything" (which is C's void))  IOW, by definition, in C a void* doesn't point to a byte instead it points into nothingness and it makes no practical sense to subtract nothingness from nothingness.  If C allowed the subtraction of two void* then the only possible result would be zero reqardless of their value because they both point to the same thing: nothing!

FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018