Re: [fpc-pascal] Pointer question

2023-08-11 Thread Hairy Pixels via fpc-pascal



> On Aug 10, 2023, at 11:37 PM, Michael Van Canneyt via fpc-pascal 
>  wrote:
> 
> This is a very dirty trick to get the offset of a field in a record.
> 
> Note that you're not dereferencing a type but a variable of type TAlignCheck 
> located
> at memory address zero. The address of w (this is what the expression is
> doing) is then the offset of w in the record.
> 
> It's probably more clear if you write it as
> p := @(TAlignCheck(nil^).w);

where is the variable located in this expression? It can't be nil can it?

Sounds like we need a compiler intrinsic to get the field address because that 
syntax is kind of crazy. :)

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pointer question

2023-08-11 Thread Nikolay Nikolov via fpc-pascal


On 8/11/23 01:23, Hairy Pixels via fpc-pascal wrote:



On Aug 10, 2023, at 2:18 PM, Michael Van Canneyt via 
fpc-pascal  wrote:

https://www.freepascal.org/docs-html/current/ref/refse15.html#x42-620003.4

This document doesn't really do a great enumerating all the operators so I'm 
not sure if the list is complete. I think the list is:

var
p: pointer;
i: ^Integer;
v: Integer;
begin
   // 1)  increment
   p := p + 1;
   inc(p);

   // 2)  increment
   p := p - 1;
   dec(p);
  
   // 3) difference

   v := p - p;
  
  // 4) subscript (inc and dereference in one step)

  v := i[1];


#4 was not  in the list for example so I wonder what others exist.


That is not true. Read that document again and focus on the part that 
starts with "Remark Free Pascal treats pointers much the same way as C 
does. This means that a pointer to some type can be treated as being an 
array of this type."


In fact, Free Pascal's documentation and exactly this page is how I 
learned about this feature a long time ago.


Nikolay
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pointer question

2023-08-10 Thread Michael Van Canneyt via fpc-pascal




On Thu, 10 Aug 2023, Hairy Pixels via fpc-pascal wrote:





On Aug 10, 2023, at 4:23 PM, Hairy Pixels  wrote:

// 4) subscript (inc and dereference in one step)
v := i[1];


#4 was not  in the list for example so I wonder what others exist.


I found another one in the typinfo.pp unit. What does,

1) taking the address of a type (@TAlignCheck) yield and
2) what does dereferencing nil yield?

Both I've never seen before until now.

type
TAlignCheck = record
  b : byte;
  w : word;
end;
var
p: pointer;
begin
p := @TAlignCheck(nil^).w;
end;


This is a very dirty trick to get the offset of a field in a record.

Note that you're not dereferencing a type but a variable of type TAlignCheck 
located
at memory address zero. The address of w (this is what the expression is
doing) is then the offset of w in the record.

It's probably more clear if you write it as
 p := @(TAlignCheck(nil^).w);

Michael.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pointer question

2023-08-10 Thread Hairy Pixels via fpc-pascal



> On Aug 10, 2023, at 4:23 PM, Hairy Pixels  wrote:
> 
> // 4) subscript (inc and dereference in one step)
> v := i[1];
> 
> 
> #4 was not  in the list for example so I wonder what others exist.

I found another one in the typinfo.pp unit. What does,

1) taking the address of a type (@TAlignCheck) yield and 
2) what does dereferencing nil yield?

Both I've never seen before until now.

type
 TAlignCheck = record
   b : byte;
   w : word;
 end;
var
 p: pointer;
begin
 p := @TAlignCheck(nil^).w;
end;

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pointer question

2023-08-10 Thread Hairy Pixels via fpc-pascal



> On Aug 10, 2023, at 2:18 PM, Michael Van Canneyt via fpc-pascal 
>  wrote:
> 
> https://www.freepascal.org/docs-html/current/ref/refse15.html#x42-620003.4

This document doesn't really do a great enumerating all the operators so I'm 
not sure if the list is complete. I think the list is:

var
   p: pointer;
   i: ^Integer;
   v: Integer;
begin
  // 1)  increment
  p := p + 1;
  inc(p);

  // 2)  increment
  p := p - 1;
  dec(p);
 
  // 3) difference
  v := p - p;
 
 // 4) subscript (inc and dereference in one step)
 v := i[1];


#4 was not  in the list for example so I wonder what others exist.


Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pointer question

2023-08-10 Thread Michael Van Canneyt via fpc-pascal




On Thu, 10 Aug 2023, Hairy Pixels via fpc-pascal wrote:





On Aug 10, 2023, at 10:49 AM, Sven Barth via fpc-pascal 
 wrote:

Then you simply aren't using them often enough. E.g. the RTTI internal code is 
full of them and additional typecasts would simply muddle up otherwise 
relatively clear code.



Here's a question, what is the full list of possible pointer operators? I 
didn't even know about pointer - pointer until now and there may be more.


https://www.freepascal.org/docs-html/current/ref/refse15.html#x42-620003.4

Michael.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pointer question

2023-08-10 Thread Hairy Pixels via fpc-pascal



> On Aug 10, 2023, at 10:49 AM, Sven Barth via fpc-pascal 
>  wrote:
> 
> Then you simply aren't using them often enough. E.g. the RTTI internal code 
> is full of them and additional typecasts would simply muddle up otherwise 
> relatively clear code. 
> 

Here's a question, what is the full list of possible pointer operators? I 
didn't even know about pointer - pointer until now and there may be more.

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pointer question

2023-08-10 Thread Sven Barth via fpc-pascal
Hairy Pixels via fpc-pascal  schrieb am
Do., 10. Aug. 2023, 18:30:

>
>
> > On Aug 10, 2023, at 5:43 AM, Bernd Oppolzer via fpc-pascal <
> fpc-pascal@lists.freepascal.org> wrote:
> >
> > PTRADD (p, i) - p is type ANYPTR, i is integer, result is of type ANYPTR
> > PTRDIFF (p1, p2) - two pointers, the result is integer
> > ANYPTR is a predefined type, compatible with every (typed pointer)
> > ADDR (x) is a function (borrowed from PL/1), which returns an ANYPTR ...
> and it is allowed for all types of variables
> > PTRCAST is the same as PTRADD (p, 0) - and is used to cast pointers
> between incompatible pointers (not type safe)
> >
>
> Not a bad idea to clarify this. Besides p + 1 the pointer math operators
> are difficult to understand and feel antiquated.
>

Then you simply aren't using them often enough. E.g. the RTTI internal code
is full of them and additional typecasts would simply muddle up otherwise
relatively clear code.

Regards,
Sven

>
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pointer question

2023-08-10 Thread Hairy Pixels via fpc-pascal



> On Aug 10, 2023, at 5:43 AM, Bernd Oppolzer via fpc-pascal 
>  wrote:
> 
> PTRADD (p, i) - p is type ANYPTR, i is integer, result is of type ANYPTR
> PTRDIFF (p1, p2) - two pointers, the result is integer
> ANYPTR is a predefined type, compatible with every (typed pointer) 
> ADDR (x) is a function (borrowed from PL/1), which returns an ANYPTR ... and 
> it is allowed for all types of variables
> PTRCAST is the same as PTRADD (p, 0) - and is used to cast pointers between 
> incompatible pointers (not type safe) 
> 

Not a bad idea to clarify this. Besides p + 1 the pointer math operators are 
difficult to understand and feel antiquated.

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pointer question

2023-08-10 Thread Hairy Pixels via fpc-pascal



> On Aug 9, 2023, at 4:37 PM, Tomas Hajny via fpc-pascal 
>  wrote:
> 
> No, the offset is not a memory address but just a number of bytes (which is 
> also the reason why you cannot add the pointers together, but you can add a 
> number to a pointer. As an example, you could use this operation to find out 
> the exact alignment of fields within a record (to check whether there's some 
> padding inserted between them) - e.g. if you aren't sure what alignment 
> directive was used for compiling a unit declaring the structure, or to 
> understand the compiler behaviour for a particuler alignment directive..

OK I understand now. It's basically an implicit cast to integer. There may have 
been historical reasons for this but I don't understand why you wouldn't just 
cast explicitly. Same goes for companions operators I think. I'd say it's one 
of the more confusion parts of the syntax actually.

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pointer question

2023-08-10 Thread Bernd Oppolzer via fpc-pascal
FWIW, when I added similar functionality to my Stanford Pascal compiler, 
I chose not to allow arithmetic

of pointers, but instead I added some functions:

PTRADD (p, i) - p is type ANYPTR, i is integer, result is of type ANYPTR
PTRDIFF (p1, p2) - two pointers, the result is integer
ANYPTR is a predefined type, compatible with every (typed pointer)
ADDR (x) is a function (borrowed from PL/1), which returns an ANYPTR ... 
and it is allowed for all types of variables
PTRCAST is the same as PTRADD (p, 0) - and is used to cast pointers 
between incompatible pointers (not type safe)


Kind regards

Bernd


Am 10.08.2023 um 10:52 schrieb Elmar Haneke via fpc-pascal:

1) what does "i := x - x;" do and what is it's purpose and why doesn't "x + x" 
work the same?


Subtracting pointers may be useful if they point to consecutive 
memory. The Result is the number of bytes between both addresses.


Adding pointers is useless, you would get a pointer pointing to some 
address in address space which has no relation to the pointers — 
presumably accessing it would rise an error.


Therefore, it is a good idea to let the compiler prevent such mistakes.


2) I've used pointer equality of course but what does "x > p" do and what is 
its purpose?


It may be useful if pointers do point into a continuous data object, 
e.g. a write-pointer inside a buffer.


Elmar

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pointer question

2023-08-10 Thread Elmar Haneke via fpc-pascal

1) what does "i := x - x;" do and what is it's purpose and why doesn't "x + x" 
work the same?


Subtracting pointers may be useful if they point to consecutive memory. 
The Result is the number of bytes between both addresses.


Adding pointers is useless, you would get a pointer pointing to some 
address in address space which has no relation to the pointers — 
presumably accessing it would rise an error.


Therefore, it is a good idea to let the compiler prevent such mistakes.


2) I've used pointer equality of course but what does "x > p" do and what is 
its purpose?


It may be useful if pointers do point into a continuous data object, 
e.g. a write-pointer inside a buffer.


Elmar


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pointer question

2023-08-09 Thread Tomas Hajny via fpc-pascal
On August 10, 2023 at 0:06:57 +0200, Hairy Pixels via fpc-pascal 
 wrote:
>> On Aug 9, 2023, at 2:54 PM, Tomas Hajny via fpc-pascal 
>>  wrote:
>> 
>>> 
>>> 1) what does "i := x - x;" do and what is it's purpose and why doesn't "x + 
>>> x" work the same?
>> 
>> Pointer subtraction is a reverse operation to adding a number to a pointer; 
>> the result of the subtraction is the offset between the two pointers.
>
>Is that different than decrementing the pointer?
>
>What would an offset between two pointers be used for? Is the offset even a 
>memory address or just a number of bytes? If you had an example usage that 
>would be interesting to see.

No, the offset is not a memory address but just a number of bytes (which is 
also the reason why you cannot add the pointers together, but you can add a 
number to a pointer. As an example, you could use this operation to find out 
the exact alignment of fields within a record (to check whether there's some 
padding inserted between them) - e.g. if you aren't sure what alignment 
directive was used for compiling a unit declaring the structure, or to 
understand the compiler behaviour for a particuler alignment directive..


>>> 2) I've used pointer equality of course but what does "x > p" do and what 
>>> is its purpose?
>> 
>> Relative position between the two locations in memory? As an example, it may 
>> be used to check whether a particular pointer points to a location between 
>> the start and the end of an allocated memory block (obviously, you'd need 
>> two comparisons for that).
>
>I guess that makes sense if a memory address with a higher value is always 
>after an address with a lower value. Is that assumption always true?

I believe that this is indeed guaranteed (at least as long as linear pointers 
are concerned, but Pascal pointer is IMHO always linear - as opposed to a 
farpointer using a segmented model or a combination of a selector and an offset.

Tomas

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pointer question

2023-08-09 Thread Hairy Pixels via fpc-pascal



> On Aug 9, 2023, at 2:54 PM, Tomas Hajny via fpc-pascal 
>  wrote:
> 
>> 
>> 1) what does "i := x - x;" do and what is it's purpose and why doesn't "x + 
>> x" work the same?
> 
> Pointer subtraction is a reverse operation to adding a number to a pointer; 
> the result of the subtraction is the offset between the two pointers.

Is that different than decrementing the pointer?

What would an offset between two pointers be used for? Is the offset even a 
memory address or just a number of bytes? If you had an example usage that 
would be interesting to see.

> 
>> 2) I've used pointer equality of course but what does "x > p" do and what is 
>> its purpose?
> 
> Relative position between the two locations in memory? As an example, it may 
> be used to check whether a particular pointer points to a location between 
> the start and the end of an allocated memory block (obviously, you'd need two 
> comparisons for that).

I guess that makes sense if a memory address with a higher value is always 
after an address with a lower value. Is that assumption always true?

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pointer question

2023-08-09 Thread Tomas Hajny via fpc-pascal
On August 9, 2023 at 22:14:17 +0200, Hairy Pixels via fpc-pascal 
 wrote:
>Playing around I had a more questions about pointer operations I've never used 
>myself.
>
>1) what does "i := x - x;" do and what is it's purpose and why doesn't "x + x" 
>work the same?

Pointer subtraction is a reverse operation to adding a number to a pointer; the 
result of the subtraction is the offset between the two pointers.


>2) I've used pointer equality of course but what does "x > p" do and what is 
>its purpose?

Relative position between the two locations in memory? As an example, it may be 
used to check whether a particular pointer points to a location between the 
start and the end of an allocated memory block (obviously, you'd need two 
comparisons for that).

Tomas

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pointer question

2023-08-09 Thread Hairy Pixels via fpc-pascal
Playing around I had a more questions about pointer operations I've never used 
myself.

1) what does "i := x - x;" do and what is it's purpose and why doesn't "x + x" 
work the same? 
2) I've used pointer equality of course but what does "x > p" do and what is 
its purpose? 

===

var
  i: int64;
  x: ^byte;
  p: Pointer;
begin
  i := x - x;
  i := x + x;  // Error: Operator is not overloaded: "^Byte" + "^Byte"

  if x > p then
;
end;

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pointer question

2023-08-09 Thread Hairy Pixels via fpc-pascal



> On Aug 8, 2023, at 11:53 PM, Sven Barth via fpc-pascal 
>  wrote:
> 
> By default @ returns a *untyped* pointer that can be assigned to any pointer 
> type. Thus is compatible with Delphi and can be controlled with the 
> $TypedAddress directive (there's a slight exception to this when you assign a 
> pointer to a function to a function variable (etc) or pass it to such a 
> parameter, because the compiler has to pick the correct overload if there are 
> multiple functions with the same name in scope). 
> 

Oh $TypedAddress, I had learned about this some time ago for another reason. I 
was always programming under the assumption @ was typed and just noticed this 
now.

The next question is why @ is untyped (if it's just for Delphi why isn't it 
behind the Delphi mode). This breaks type safety does it not? 

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Pointer question

2023-08-08 Thread Sven Barth via fpc-pascal
Hairy Pixels via fpc-pascal  schrieb am
Mi., 9. Aug. 2023, 04:59:

> I just noticed this by accident and I don't understand. Why does " x :=
> @r; " compile? I would expect it to fail like the next line where I cast to
> the explicit type.
>
> type
>   TMyRec = record end;
>   PMyRec = ^TMyRec;
> var
>   x: PByte;
>   r: TMyRec;
> begin
>   x := @r;// works
>   x := PMyRec(@r);  // fails
> end.


By default @ returns a *untyped* pointer that can be assigned to any
pointer type. Thus is compatible with Delphi and can be controlled with the
$TypedAddress directive (there's a slight exception to this when you assign
a pointer to a function to a function variable (etc) or pass it to such a
parameter, because the compiler has to pick the correct overload if there
are multiple functions with the same name in scope).

Regards,
Sven

>
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] Pointer question

2023-08-08 Thread Hairy Pixels via fpc-pascal
I just noticed this by accident and I don't understand. Why does " x := @r; " 
compile? I would expect it to fail like the next line where I cast to the 
explicit type.

type
  TMyRec = record end;
  PMyRec = ^TMyRec;
var
  x: PByte;
  r: TMyRec;
begin
  x := @r;// works
  x := PMyRec(@r);  // fails
end

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal