View Issue Details

IDProjectCategoryView StatusLast Update
0036792FPCOtherpublic2020-12-23 07:31
Reporterchebmaster Assigned To 
Status newResolutionopen 
Summary0036792: "Conversion between ordinals and pointers is not portable" is misleading
Description"Conversion between ordinals and pointers is not portable" should be "Fixed-bitness pointer math detected, not portable" or "There is a stray longint in your pointer math, check your type-casts" or something equally informative.

I was under false impression this warning was referring to pointer arithmetic *in general* being not portable to platforms with no pointers so I struggled for many years trying and failing to port my game engine to x86-64. It kept crashing horribly while I kept ignoring humongous herds of these warnings.
Steps To ReproduceBe a "A true Jedi needs no manuals" fool like me.
Forget what "ordinals" are, think it's a generic fancy name for unsigned integers of any bitness.
Additional Information//My original faulty code:
f_Size: longint
function TChepersyMemoryManagerChunk.Alloc: pointer;
var k: integer;
Exit(pointer(ptruint(Self) + ptruint(k) * f_Size));

//My fixed code (warning disappeared):
Exit(pointer(ptruint(Self) + ptruint(k * f_Size)));

Would be worth nothing if I was a newbie, but I am a foolish but still experienced hobbyist coder who started using Turbo Pascal as far back as 1988 and Free Pascal since version 1.1 (a year or so before 1.9). My best and lost achievement (a true Jedi needs no backups) was a multi-threaded game engine for MS-DOS written in Turbo Pascal + Turbo Assembler that was using a timer interrupt handler to switch thread contexts.
TagsNo tags attached.
Fixed in Revision
Attached Files


Thaddy de Koning

2020-03-14 11:17

reporter   ~0121604

Last edited: 2020-03-14 11:18

View 3 revisions

{$pointermath on} and skip the f_size part?


2020-03-14 15:22

reporter   ~0121610

In this case, f_size cannot be known at compile time.
But fellows from the board already provided me with a solution:
Exit(Pointer(Self) + k * f_Size); // simply use untyped pointer

I guess I have developed bad habits from working with Delphi 4 and fp 1.1 (cast it to cardinal, otherwise nothing works). I had weeded out all my cardinals but simply replaced them with ptruints.


2020-03-14 18:42

reporter   ~0121614

PByte(self) is still better than pointer(self).
In a strict meaning, the element size of untyped pointer is undefined.
That's why pointer(self) is not allowed for pointermath in Delphi.


2020-03-15 09:04

reporter   ~0121615

P.S. Okay, confused now. Even pointer(ptruint(bigptr) + longint1 * longint2) works correctly.
What does "Conversion between ordinals and pointers is not portable" mean, then?
This warning *only* appears when compiling for the 32-bit platform. The x64 cross-compiler does not issue it.


2020-12-22 18:53

reporter   ~0127769

Is this fixed or rejected due to the fact that fpc team didnt see this as a bug?


2020-12-23 07:31

reporter   ~0127774

Use Inc() and Dec() for pointers, as mentioned in

It's very simple and no need in unsafe casts.

Issue History

Date Modified Username Field Change
2020-03-13 18:54 chebmaster New Issue
2020-03-14 11:17 Thaddy de Koning Note Added: 0121604
2020-03-14 11:17 Thaddy de Koning Note Edited: 0121604 View Revisions
2020-03-14 11:18 Thaddy de Koning Note Edited: 0121604 View Revisions
2020-03-14 15:22 chebmaster Note Added: 0121610
2020-03-14 18:42 nanobit Note Added: 0121614
2020-03-15 09:04 chebmaster Note Added: 0121615
2020-12-22 18:53 Shpend Note Added: 0127769
2020-12-23 07:31 serbod Note Added: 0127774