Recent

Author Topic: How to freely assign typed and untyped pointers?  (Read 1636 times)

furious programming

  • Hero Member
  • *****
  • Posts: 858
How to freely assign typed and untyped pointers?
« on: December 16, 2022, 01:43:53 pm »
Is it possible to disable strong typing of pointers so that I can freely assign a wide variety of typed and untyped pointers to each other? The point is to be able to explicitly (without casting) assign e.g. PInteger to a pointer variable of any type, e.g. Pointer, PChar, PSomeFunction, and vice versa?

I don't mean {$TYPEDADDRESS} here, because it's not about getting an address to assign to a variable, but about directly assigning pointers of different types to each other (without casting), and also about passing pointers in parameters, no matter what pointer type this parameter is.

Can I somehow disable this damn strong typing so that the compiler doesn't throw pointer type mismatch errors?
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9908
  • Debugger - SynEdit - and more
    • wiki
Re: How to freely assign typed and untyped pointers?
« Reply #1 on: December 16, 2022, 02:17:04 pm »
I don't know if an option as you seek exists....

If not, a workaround may be to create assignment operators. Not tested though.

Thaddy

  • Hero Member
  • *****
  • Posts: 14382
  • Sensorship about opinions does not belong here.
Re: How to freely assign typed and untyped pointers?
« Reply #2 on: December 16, 2022, 02:38:28 pm »
If not, a workaround may be to create assignment operators. Not tested though.
Does not work, because the compiler gives an impossible overload error. That is because e.g. Pchar and PInteger are still pointer types. and the result of the operator is untyped pointer. Strong typing is GOOD, not BAD, NOT C
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

furious programming

  • Hero Member
  • *****
  • Posts: 858
Re: How to freely assign typed and untyped pointers?
« Reply #3 on: December 16, 2022, 02:55:51 pm »
I don't know if an option as you seek exists....

It would be nice if there was a switch to disable pointer type checking. Currently, the only solution is ubiquitous casting, which only annoys and makes the code one big mess. This is a nuisance especially when the code is low-level, where the use of various pointers is necessary, but where typed pointers allows to keep the code readable.

For example, I have a base structure and its pointer type declared. I have a second structure that embeds the first one and extends it with more fields - a typed pointer is also declared to it. Now I want to pass second struct pointer to function having parameter as base struct pointer and I can't because "type mismatch". Also, I can't assign a pointer variable of the second type to a pointer variable of the base type, because such polymorphism also results in "type mismatch".

Quote
If not, a workaround may be to create assignment operators. Not tested though.

Is it possible to create an operator in such a way that it allows pointers of any type to be assigned to each other? One operator, but universal (generic) for all typed and untyped pointers?



Strong typing is GOOD, not BAD, NOT C

Strong typing is good for those who can't think and who need to be led by the hand by the compiler. Currently, FPC is acting like an overprotective daddy saying "don't do this, don't do that or you could get hurt". And it does so despite the fact that I want to perform the most correct assignment or pass a function-pointer. I want to do what is right and what I think is right in my code, and if I can hurt myself, I want to hurt myself — I'll get a runtime error, fix the code, and fix the problem. Errors are GOOD, not being able to compile code due to implied errors is BAD.

Also, saying strong typing is good is nonsense, because all you have to do is add a cast and the compiler won't mind assigning different pointers. So why force a cast when it just lengthens the code and secore nothing? This doesn't make sense, so there should be a compiler switch so that all pointers can be treated the same.
« Last Edit: December 16, 2022, 02:58:35 pm by furious programming »
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

jamie

  • Hero Member
  • *****
  • Posts: 6131
Re: How to freely assign typed and untyped pointers?
« Reply #4 on: December 16, 2022, 03:00:20 pm »
You can cast over a typed pointer with a generic pointer.

You simply can't cast over a type with another type that has larger memory coverage.
The only true wisdom is knowing you know nothing

furious programming

  • Hero Member
  • *****
  • Posts: 858
Re: How to freely assign typed and untyped pointers?
« Reply #5 on: December 16, 2022, 03:10:53 pm »
Ok, so look at the test program below:

Code: Pascal  [Select][+][-]
  1. {$MODE OBJFPC}
  2.  
  3. type
  4.   PFoo = ^TFoo;
  5.   TFoo = record
  6.     A: Integer;
  7.   end;
  8.  
  9. type
  10.   PBar = ^TBar;
  11.   TBar = record
  12.     Foo: TFoo;
  13.     B:   Integer;
  14.   end;
  15.  
  16.   procedure DoSomething(AFoo: PFoo);
  17.   begin
  18.     AFoo^.A := 100;
  19.   end;
  20.  
  21. var
  22.   Foo: PFoo;
  23.   Bar: PBar;
  24. begin
  25.   New(Foo);
  26.   New(Bar);
  27.  
  28.   DoSomething(Foo);
  29.   DoSomething(Bar); // Error: Incompatible type for arg no. 1: Got "PBar", expected "PFoo"
  30.  
  31.   Foo := Bar; // Error: Incompatible types: got "PBar" expected "PFoo"
  32. end.

What can be done to make the above code compile but without using casts? Of course I can cast and fix the problem:

Code: Pascal  [Select][+][-]
  1. var
  2.   Foo: PFoo;
  3.   Bar: PBar;
  4. begin
  5.   New(Foo);
  6.   New(Bar);
  7.  
  8.   DoSomething(Foo);
  9.   DoSomething(PFoo(Bar)); // no error, no type checking, runtime errors are possible
  10.  
  11.   Foo := PFoo(Bar); // no error, no type checking, runtime errors are possible
  12. end.

but I don't want to use casting everywhere.
« Last Edit: December 16, 2022, 03:18:23 pm by furious programming »
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5486
  • Compiler Developer
Re: How to freely assign typed and untyped pointers?
« Reply #6 on: December 16, 2022, 03:17:15 pm »
What can be done to make the above code compile but without using casts? Of course I can cast and fix the problem:

{ snip }

but I don't want to use casting everywhere.

Though luck. This is how the language works and this is a strength of the language. This will not be changed and we also won't provide mechanisms (aside from casting) to weaken this.

Thaddy

  • Hero Member
  • *****
  • Posts: 14382
  • Sensorship about opinions does not belong here.
Re: How to freely assign typed and untyped pointers?
« Reply #7 on: December 16, 2022, 03:20:26 pm »
Maybe this https://www.freepascal.org/docs-html/rtl/system/opaquepointer.html will help.
I introduced that a couple of years ago, but I have to test that too, because it was meant for C interfacing.
[edit]tested that too, no luck.
« Last Edit: December 16, 2022, 03:24:35 pm by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

jamie

  • Hero Member
  • *****
  • Posts: 6131
Re: How to freely assign typed and untyped pointers?
« Reply #8 on: December 16, 2022, 03:21:32 pm »
Overloaded DoSomething Procedures?
The only true wisdom is knowing you know nothing

furious programming

  • Hero Member
  • *****
  • Posts: 858
Re: How to freely assign typed and untyped pointers?
« Reply #9 on: December 16, 2022, 03:24:52 pm »
This will not be changed and we also won't provide mechanisms (aside from casting) to weaken this.

You've already done that by giving the ability to cast to get around type mismatch errors, and by giving the {$TYPEDADDRESS} switch to bypass all that "strength" of the language. It's just a pity that you gave half the possibilities.



Maybe this https://www.freepascal.org/docs-html/rtl/system/opaquepointer.html will help.
I introduced that a couple of years ago, but I have to test that too, because it was meant for C interfacing.

Interesting, I will investigate this. Thank you.

BTW: opaque typed pointers for records can be created easily — language features are enough:

Code: Pascal  [Select][+][-]
  1. {$MODESWITCH ADVANCEDRECORDS}
  2.  
  3. type
  4.   PFoo = ^TFoo;
  5.   TFoo = record private
  6.     { hidden content }
  7.   end;

PFoo is a typed pointer, but it is also opaque outside of the declaration unit, so win-win.
« Last Edit: December 16, 2022, 03:59:10 pm by furious programming »
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

jamie

  • Hero Member
  • *****
  • Posts: 6131
Re: How to freely assign typed and untyped pointers?
« Reply #10 on: December 16, 2022, 03:28:09 pm »
so, it appears you are looking for some sort of type info from an unknown member being entered?
The only true wisdom is knowing you know nothing

furious programming

  • Hero Member
  • *****
  • Posts: 858
Re: How to freely assign typed and untyped pointers?
« Reply #11 on: December 16, 2022, 03:34:28 pm »
@jamie: I need the ability to assign pointers of any type to each other (but still have typed pointers), as well as pass data pointers and function pointers in parameters. All without casting, type checking and other "smart" compiler behaviors. Which is something that is normal in C.

Currently, I either have to use a cast, which only makes the code unnecessarily long and reduces its readability:

Code: Pascal  [Select][+][-]
  1. var
  2.   Foo: PFoo;
  3.   Bar: PBar;
  4. begin
  5.   New(Foo);
  6.   New(Bar);
  7.  
  8.   DoSomething(Foo);
  9.   DoSomething(PFoo(Bar)); // ordinary casting, works fine
  10.  
  11.   Foo := PFoo(Bar); // ordinary casting, works fine
  12. end.

or use the {$TYPEDADDRESS OFF} switch and do this magic with the @ operator:

Code: Pascal  [Select][+][-]
  1. {$TYPEDADDRESS OFF}
  2.  
  3. var
  4.   Foo: PFoo;
  5.   Bar: PBar;
  6. begin
  7.   New(Foo);
  8.   New(Bar);
  9.  
  10.   DoSomething(Foo);
  11.   DoSomething(@Bar^); // no casting, works fine, but it looks terrible...
  12.  
  13.   Foo := @Bar^; // no casting, works fine, but it looks terrible...
  14. end.

Both solutions allows to bypass type checking, but both require to do magic in the code to keep the compiler shut its mouth. I'm not happy with something like this. In code written in Free Pascal, but in the C-style, I can't handle polymorphism normally, because I have to fight with a big-headed compiler.

And I just need to pass an arbitrary pointer, making sure it's valid myself:

Code: Pascal  [Select][+][-]
  1. {$TYPEDADDRESS OFF}
  2. {$TYPEDPOINTER OFF} // something like this would be excellent
  3.  
  4. var
  5.   Foo: PFoo;
  6.   Bar: PBar;
  7. begin
  8.   New(Foo);
  9.   New(Bar);
  10.  
  11.   DoSomething(Foo);
  12.   DoSomething(Bar); // no casting, no type checking, should compile without errors
  13.  
  14.   Foo := Bar; // no casting, no type checking, should compile without errors
  15. end.
« Last Edit: December 16, 2022, 03:50:28 pm by furious programming »
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

jamie

  • Hero Member
  • *****
  • Posts: 6131
Re: How to freely assign typed and untyped pointers?
« Reply #12 on: December 16, 2022, 03:49:55 pm »
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Grids, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     procedure Button1Click(Sender: TObject);
  17.   private
  18.  
  19.   public
  20.  
  21.   end;
  22. TMyTypeINFO = Object
  23.    AType:Integer; // Use a set insead etc.
  24.   End;
  25. TMyType1 = Object(TMyTypeInfo)
  26.   S:String[100];
  27.   B:Byte;
  28.  End;
  29. TMyType2 = Object(TMyTypeInfo)
  30.   X:Integer;
  31.   Y:Integer;
  32.   End;
  33. PMyTypeInfo = ^TMyTypeInfo;
  34. PMyType1 = ^TMyType1;
  35. PMyType2 = ^TMyType2;
  36. var
  37.   Form1: TForm1;
  38.  
  39. implementation
  40.  
  41. {$R *.lfm}
  42.  
  43. { TForm1 }
  44. Function DoSomething(AUnknown:PMyTypeInfo):Boolean;
  45. Begin
  46. Result := True;
  47.   Case AUnknown^.AType of
  48.    0:;
  49.    1:;
  50.   Else Result := false;
  51.   end;
  52. End;
  53. procedure TForm1.Button1Click(Sender: TObject);
  54. Var
  55.   A:PMyType1;
  56.   B:PMyType2;
  57. begin
  58.   New(A);
  59.   New(B);
  60.   DoSomething(A);
  61.   DOSomething(B);
  62.   Dispose(A);
  63.   Dispose(B);
  64. end;
  65.  
  66. end.
  67.  

I do code like this in various places where I have different constructs.
 
There is nothing like the old Objects to come to the rescue.

 You can also do this with Classes where a simple TObject as the intry will do.

The example I posted here compiles without complaints.


The only true wisdom is knowing you know nothing

furious programming

  • Hero Member
  • *****
  • Posts: 858
Re: How to freely assign typed and untyped pointers?
« Reply #13 on: December 16, 2022, 03:55:29 pm »
@jamie: your approach requires writing even more code. Normal casting is more convenient to use.
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

jamie

  • Hero Member
  • *****
  • Posts: 6131
Re: How to freely assign typed and untyped pointers?
« Reply #14 on: December 16, 2022, 03:57:37 pm »
really?
if you say so.

Then maybe all you need is Procedure overloads which only can be resolves at compile time.

Good luck.
The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018