Recent

Author Topic: Are pointers normalized before comparison  (Read 9349 times)

joho

  • Jr. Member
  • **
  • Posts: 69
  • Joaquim Homrighausen
    • ~/JoHo
Are pointers normalized before comparison
« on: September 30, 2017, 01:01:56 am »
Sorry if use the wrong term here, and possibly because some target environments may not suffer from this, but:

Does the compiler normalize all pointers before doing comparisons?

p1, p2 :pointer;

p1 := @p1block;
p2 := @p2block;

if (p1 > p2) then ...

Or do I have to cast them to something (and possibly something unsigned too?)



Eugene Loza

  • Hero Member
  • *****
  • Posts: 671
    • My games in Pascal
Re: Are pointers normalized before comparison
« Reply #1 on: September 30, 2017, 05:55:54 am »
I'm not exactly sure what are you trying to achieve. But in your example everything should work fine for both local and global variables, as "pointers" are 64-bit (32-bit on 32-bit platforms) integers referencing to a memory address. If you need to get a numeric of the pointer you can easily LongWord(aPointer) it. However, as I've said, it's just an integer, so you can simply do inc(aPointer,4) to increase aPointer by 4 bytes (very useful). E.g. you can even if (p1 > p2+1024) then ...
See also https://www.freepascal.org/docs-html/ref/refse15.html . The program PointerArray; example looks like it.
« Last Edit: September 30, 2017, 06:05:27 am by Eugene Loza »
My FOSS games in FreePascal&CastleGameEngine: https://decoherence.itch.io/ (Sources: https://gitlab.com/EugeneLoza)

Leledumbo

  • Hero Member
  • *****
  • Posts: 8757
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Are pointers normalized before comparison
« Reply #2 on: September 30, 2017, 06:53:26 am »
However, as I've said, it's just an integer, so you can simply do inc(aPointer,4) to increase aPointer by 4 bytes.
Watch out, that applies only for untyped pointer or pointer of something of byte size. In other cases, Inc() increases as much as the size of type the pointer points to. e.g.:
Code: Pascal  [Select][+][-]
  1. var
  2.   p: PByte;
  3.   q: PLongWord;
  4. begin
  5.   PtrUInt(p) := $1111111111111110;
  6.   PtrUInt(q) := $1111111111111110;
  7.   Inc(p,4);
  8.   Inc(q,4);
  9.   WriteLn(HexStr(PtrUInt(p),SizeOf(p) * 2));
  10.   WriteLn(HexStr(PtrUInt(q),SizeOf(q) * 2));
  11. end.
  12.  
output:
Code: [Select]
1111111111111114
1111111111111120

joho

  • Jr. Member
  • **
  • Posts: 69
  • Joaquim Homrighausen
    • ~/JoHo
Re: Are pointers normalized before comparison
« Reply #3 on: September 30, 2017, 04:17:08 pm »
Sorry if I was unclear ... what I meant is if it's save to assume that the compiler does *unsigned* pointer arithmetics (when it comes to comparing pointers)? Or do I have to cast them as CARDINAL or similar? For a ring buffer, I need to know where the current position is, and where the head and tail is. So if these are signed comparison, there is a (theoretical) chance that a signed comparison would barf, no?

munair

  • Hero Member
  • *****
  • Posts: 798
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: Are pointers normalized before comparison
« Reply #4 on: October 01, 2017, 06:06:30 am »
Normally, when you access data in a buffer, you just point to the position of whatever data structure you use and memory access will be handled for you. And if you shift the data up or down the buffer, addresses will be updated when needed.
« Last Edit: October 01, 2017, 07:39:11 am by munair »
keep it simple

munair

  • Hero Member
  • *****
  • Posts: 798
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: Are pointers normalized before comparison
« Reply #5 on: October 01, 2017, 06:24:44 am »
You can also set up a data structure and include a position variable. This will give you complete control over the number of elements, which one is first or last, and you can change/shift them at will. But this is just an example, since I do not know what kind of data you are talking about.
keep it simple

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11445
  • FPC developer.
Re: Are pointers normalized before comparison
« Reply #6 on: October 01, 2017, 12:19:43 pm »
Sorry if I was unclear ... what I meant is if it's save to assume that the compiler does *unsigned* pointer arithmetics (when it comes to comparing pointers)? Or do I have to cast them as CARDINAL or similar?

Yes, it should be safe for unsigned pointers in 32-bit and 64-bit memory flat models.

In segmented models (16-bit x86) everything is different.

ASerge

  • Hero Member
  • *****
  • Posts: 2240
Re: Are pointers normalized before comparison
« Reply #7 on: October 01, 2017, 07:41:37 pm »
Sorry if I was unclear ... what I meant is if it's save to assume that the compiler does *unsigned* pointer arithmetics
Pointer arithmetics is signed:
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. program Project1;
  3.  
  4. var
  5.   A, B: Integer;
  6. begin
  7.   Writeln(PtrInt(@A) - PtrInt(@B));
  8.   Writeln(@A - @B);
  9.   Writeln(PtrUInt(@A) - PtrUInt(@B)); // Wrong
  10.   Readln;
  11. end.
Code: [Select]
-4
-4
18446744073709551612

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Are pointers normalized before comparison
« Reply #8 on: October 01, 2017, 07:52:12 pm »
Sorry if I was unclear ... what I meant is if it's save to assume that the compiler does *unsigned* pointer arithmetics
Pointer arithmetics is signed:
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. program Project1;
  3.  
  4. var
  5.   A, B: Integer;
  6. begin
  7.   Writeln(PtrInt(@A) - PtrInt(@B));
  8.   Writeln(@A - @B);
  9.   Writeln(PtrUInt(@A) - PtrUInt(@B)); // Wrong
  10.   Readln;
  11. end.
Code: [Select]
-4
-4
18446744073709551612

The results here are different:
Quote
-16
-16
-16

mse

  • Sr. Member
  • ****
  • Posts: 286
Re: Are pointers normalized before comparison
« Reply #9 on: October 01, 2017, 07:58:42 pm »
Sorry if use the wrong term here, and possibly because some target environments may not suffer from this, but:

Does the compiler normalize all pointers before doing comparisons?

Yes.
Quote
p1, p2 :pointer;

p1 := @p1block;
p2 := @p2block;

if (p1 > p2) then ...

Or do I have to cast them to something (and possibly something unsigned too?)
No.

ASerge

  • Hero Member
  • *****
  • Posts: 2240
Re: Are pointers normalized before comparison
« Reply #10 on: October 01, 2017, 11:28:06 pm »
The results here are different:
Quote
-16
-16
-16
1. The first and second lines show that the arithmetic is signed.
2. In the 32 compiler, if the result does not fit in 32 bits, but is fit in Int64, then it will be Int64, for compatibility. Use the additional PtrUInt (Result).

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Are pointers normalized before comparison
« Reply #11 on: October 01, 2017, 11:40:03 pm »
The results here are different:
Quote
-16
-16
-16
1. The first and second lines show that the arithmetic is signed.
2. In the 32 compiler, if the result does not fit in 32 bits, but is fit in Int64, then it will be Int64, for compatibility. Use the additional PtrUInt (Result).

Thank you.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Are pointers normalized before comparison
« Reply #12 on: October 01, 2017, 11:40:37 pm »
The results here are different:
Quote
-16
-16
-16
1. The first and second lines show that the arithmetic is signed.
no it only shows that you asked the compiler to treat it as a signed integer by type casting it to one.
2. In the 32 compiler, if the result does not fit in 32 bits, but is fit in Int64, then it will be Int64, for compatibility. Use the additional PtrUInt (Result).
erm you lost me here, there is no way in a 32bit application a pointer will ever be treated as a 64bit.
Your example is wrong in all counts, mostly because you force a specific translation of the data.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

ASerge

  • Hero Member
  • *****
  • Posts: 2240
Re: Are pointers normalized before comparison
« Reply #13 on: October 02, 2017, 01:12:18 am »
no it only shows that you asked the compiler to treat it as a signed integer by type casting it to one.
Code: Pascal  [Select][+][-]
  1. Writeln(@A - @B);
And where is the cast?

Quote
there is no way in a 32bit application a pointer will ever be treated as a 64bit.
After casting this integer computation. Compile this in 32 bit
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. program Project1;
  3.  
  4. var
  5.   A, B: Cardinal;
  6. begin
  7.   A := 1;
  8.   B := 2;
  9.   Writeln(A - B);
  10.   Readln;
  11. end.
This from assemble code (the compiler selects 64-bit arithmetic for 32-bit types):
Quote
...
   movl   %eax,%ebx
   movl   U_$P$PROJECT1_$$_A,%esi
   movl   $0,%eax
   movl   U_$P$PROJECT1_$$_B,%edx
   movl   $0,%ecx
   subl   %edx,%esi
   sbbl   %ecx,%eax
   pushl   %eax
   pushl   %esi
   movl   %ebx,%edx
   movl   $0,%eax
   call   fpc_write_text_int64
   call   FPC_IOCHECK
...

Quote
Your example is wrong in all counts
Your message is wrong in all counts  :)

munair

  • Hero Member
  • *****
  • Posts: 798
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: Are pointers normalized before comparison
« Reply #14 on: October 02, 2017, 08:37:31 am »
Why would pointers be negative in today's flat memory model? The only experience I had with negative addresses was with computer languages in 16 bit environments that did not support WORD data types. So addresses between 32768 and 65535 were automatically given as signed integers between -32768 and -1. The trick was to always "convert" to unsigned integers by adding 65536 and store them as long integers. It was dirty, but it worked. In today's flat memory models, pointers should support the unsigned range of the environment (32 or 64 bits).
keep it simple

 

TinyPortal © 2005-2018