Any Ptr woes

General FreeBASIC programming questions.
Post Reply
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Any Ptr woes

Post by deltarho[1859] »

Code: Select all

Type udt
   As Ulong counter = 8
End Type

Dim As udt test
Dim testptr As Any Ptr = @test

Print testptr->counter
'Print (*testptr).counter
'Print *(cast(ulong ptr, testptr)).counter

Sleep
The first Print comes up with error 71:Incomplete type, before 'counter'

The second Print comes up with error 71:Incomplete type, before ')'

The third Print comes up with error 3:Expected End-of-Line, found "."

You can see what I am trying to do – print counter via testptr.

What I find frustrating is the compiler giving us the opportunity to use 'As Any' but when we use it, it requires us to be specific.

What I need is a fourth Print that works. :)
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Any Ptr woes

Post by deltarho[1859] »

This works:

Code: Select all

Print *(cast(ulong ptr, testptr))
But what if I had:

Code: Select all

Type udt
As Ulong index = 5
As Ulong counter = 8
End Type
I would now get 5.

But

Code: Select all

Print *(cast(ulong ptr, testptr+SizeOf(Ulong))) ' [1]
gives me 8.

There must be a better way than [1] to get at counter?

Added: There is

Code: Select all

Print (*cast(ulong ptr, testptr+OffsetOf(udt, counter)))
Never used OffsetOf before. :)

Using OffsetOf is a bit of a dog's dinner – it doesn't solve the first post – or does it?
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Any Ptr woes

Post by coderJeff »

Here's the code step-by-step that hopefully will help anyone with similar woes:

'udt' is a user defined type, to describe some the contents of a memory location with some particular structure:

Code: Select all

Type udt
   As Ulong index = 5
   As Ulong counter = 8
End Type
'test' is a variable (stored somewhere in memory) having the structure of 'udt' and can be accessed through the variable and UDT member.

Code: Select all

Dim As udt test
print test.counter
'testudtptr' is a pointer (a memory address) that tells us where test is located in memory, and that the data at that memory location has the structure of 'udt'. The compiler knows what structure to use when 'testudtptr' is accessed because the type of pointer is known by the variable's type:

Code: Select all

Dim as udt ptr testudtptr = @test
print testudtptr->counter
print (*testudtptr).counter
'testptr' is a memory address but by typing it as 'any ptr' there is no expectation of what kind of structure is located at that memory address. The compiler knows that it is a memory location but has been told to forget what ever kind of structure might be there.

Code: Select all

Dim testptr As Any Ptr = @test
To access the members of a structure (UDT) through a pointer, the compiler needs to know what that pointer is pointing to. By casting the any pointer back to the original 'udt' type we can tell the compiler how the pointer (memory location) should be accessed and what structure is located there:

Code: Select all

Type udt
   As Ulong index = 5
   As Ulong counter = 8
End Type

Dim As udt test
Dim testptr As Any Ptr = @test

print cast( udt ptr, testptr )->counter
print cptr( udt ptr, testptr )->counter
print (*cast( udt ptr, testptr )).counter 
print (*cptr( udt ptr, testptr )).counter
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Any Ptr woes

Post by deltarho[1859] »

Wow, thanks coderJeff. I have just put a link to your post in my Notes.txt file on my desktop, which now has 1085 lines of tips which I may forget. I often search Notes.txt when something rings a bell, but I cannot remember the tip. :)

Of the four possibilities, I will opt for the third one; that would never have occurred to me. I should remember that a UDT is a datatype. I have an aversion to the C operator ->. To my mind, it should not be in BASIC.

Thanks again – I am certain that many others will find your post very helpful. :wink:
Post Reply