Jump to content
Mike Torrettinni

Is Record method solution or a bad hack for pointer fields?

Recommended Posts

I have customized INI file, so need my own record structure. So I have:

 

TINIRec = record
  Section,  Key, Value: string;
  IsSectionHeader: boolean; 
  ...
end;

And I have ComparedData array that contains pointer to TINIRec:

 

TComparedData = record
  PointerRecType: TRecType; // this identifies RecPointer as TINIRec
  RecPointer: Pointer; // Pointer to TINIRec
  ...
end;

ComparedData = TArray<TComparedData>

 

So, when ComparedData is filled with correct data from INI file, I access the content like this:

if ComparedData[x].RecPointer <> nil then
  IsINILineAHeaderLine := TINIRec(ComparedData[x].RecPointer^).IsSectionHeader;

Of course the check for nil pointer has to be everywhere...

 

So, if I set a record function like this I can avoid checking for nil record:

TComparedData = record
  PointerRecType: TRecType; // this identifies RecPointer as TINIRec
  RecPointer: Pointer; // Pointer to TINIRec
  ...
  function IsSectionHeaderLine: boolean;
end;

function TComparedData.IsSectionHeaderLine: boolean;
begin
  Result := false;
    if RecPointer <> nil then
      Result := TINIRec(RecPointer^).IsSectionHeader;
end;

 

and the call without checking for nil pointer:

IsINILineAHeaderLine := ComparedData[x].IsSectionHeader;

Is this a bad way to deal with pointers? Can this case issues later on, unexpected?

Share this post


Link to post

No, that's perfectly valid.

 

But why don't you decleare RecPointer as ^TIniRec and save yourself the typecasting? Or are there pointers to different types? If the latter, why do you use records instead of classes?

 

Actually I don't think this should compile:

TComparedData = record
  PointerRecType: TRecType; // this identifies RecPointer as TINIRec
  RecPointer: Pointer; // Pointer to TINIRec
  ...
  function IsSectionHeaderLine: boolean;
end;

function TComparedData.IsSectionHeaderLine: boolean;
begin
  Result := false;
    if RecPointer <> nil then
      Result := TINIRec(RecPointer^).IsSectionHeader; // <-- this should not compile as RecPointer is an untyped pointer and therefore RecPointer^ is undefined.
end;

 

Edited by dummzeuch
  • Thanks 1

Share this post


Link to post
16 minutes ago, dummzeuch said:

Actually I don't think this should compile:

Hm... it compiles and runs here just fine. Or is it just luck and will fail sooner or later?

 

Maybe I should add more details: I have PINIRec = ^TINIRec; and RecPointer is set with:

 

type
  PINIRec = ^TINIRec;

var 
  vRecPointer: PINIRec;
begin
  ...
  New(vRecPointer);
  vRecPointer^ := Default(TINIRec);
  ...// here set vRecPointer values from INILine...
  ComparedData[x].RecPointer := @vRecPointer^; 

Does this make sense?

Edited by Mike Torrettinni

Share this post


Link to post
10 hours ago, David Schwartz said:

check out BigINI from this guy, the latest (v5) is most interesting.

 

http://www.hinzen.de/delphi/index.html

 

No diffs, but it extends basic INI file managment quite nicely.

 

I've used it for years. (And added several new things.)

 

Thanks, but is not really using record methods. or dealing with pointers like I do. Perhaps you were trying to point out something else?

Share this post


Link to post

I can't tell whether you're trying to solve a programming problem, or if you're just doing mental calisthenics trying to use different programming constructs in strange ways.

 

I realize some people love using records and pointers to them in Pascal. But I spent 10+ years using c and c++ before getting into Delphi and I have always gotten confused about which side of the variable the ^ goes on and why you need to use it with a '.' because in c/c++ the '->' always goes on the right, and you never use any two of '.', '&', '*', and '->' next to each other.

 

Maybe it's the same way some people have trouble grasping the difference between how ++i and i++ work in a for loop. 

 

Suffice it to say I bet you've used pointers in Delphi more in the past month than I've used them in the past 10 years. 

 

That class DOES show some effective uses of inheritance tho.

  • Like 1

Share this post


Link to post
6 hours ago, David Schwartz said:

I have always gotten confused about which side of the variable the ^ goes on and why you need to use it with a '.' because in c/c++ the '->' always goes on the right, and you never use any two of '.', '&', '*', and '->' next to each other.

It's personal. I, contrary, always stuck on C's ((foo *)bar**) etc. Pascal has different symbols for taking an address and dereferencing and it's very convenient.

  • Like 1

Share this post


Link to post
On 4/1/2020 at 12:14 PM, dummzeuch said:

But why don't you decleare RecPointer as ^TIniRec and save yourself the typecasting? Or are there pointers to different types? If the latter, why do you use records instead of classes?

@dummzeuch I'm not sure what you are thinking here... classes instead of records? How can I use defined different classes that Pointer will point to?

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×