constant pointer to global struct member

General FreeBASIC programming questions.
Post Reply
Mysoft
Posts: 836
Joined: Jul 28, 2005 13:56
Location: Brazil, Santa Catarina, Indaial (ouch!)
Contact:

constant pointer to global struct member

Post by Mysoft »

i guess the following code should be possible

Code: Select all

type MyStruct
  A as integer
end type

static shared as MyStruct tA
const pTA = @tA
specially giving that i can access the constant pointer in ASM

Code: Select all

asm mov eax, [tA+offsetof(MyStruct,tA)]
which gives another issue... that variables inside structs are not accessible from ASM in the conventional ways...
should those be notified as bugs... or feature requests?
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: constant pointer to global struct member

Post by MrSwiss »

Mysoft wrote:which gives another issue... that variables inside structs are not accessible from ASM in the conventional ways...
should those be notified as bugs... or feature requests?
The Const (even if used as qualifier only) is responsible, that the members
can't be changed, however, this is "expected behaviour" and not a bug.

Try something like: static shared as MyStruct ptr ptA = @tA
This can even be indexed, as a normal data-type ptr.

Assembly can access the ptr (but can't change the members it points to),
if we are talking about FB's inline ASM. (Const makes it: "read only")
Mysoft
Posts: 836
Joined: Jul 28, 2005 13:56
Location: Brazil, Santa Catarina, Indaial (ouch!)
Contact:

Re: constant pointer to global struct member

Post by Mysoft »

MrSwiss wrote:The Const (even if used as qualifier only) is responsible, that the members
can't be changed, however, this is "expected behaviour" and not a bug.
no thats not what the const there means... it just mean the value of the ptr is constant which IS, meaning the pointer value is pre-calculated at compiled at compile time... which is what it suppose to do there (its not a ptr to a const...)

so i can do stuff like

Code: Select all

 static shared as ulong ptr pTarget(...) = { @Struct.A , @Struct.B , @Struct.C }
which works when the variable is outside a struct...
MrSwiss wrote:Try something like: static shared as MyStruct ptr ptA = @tA
This can even be indexed, as a normal data-type ptr.
it works with @tA but it does not work with @tA.A
MrSwiss wrote:Assembly can access the ptr (but can't change the members it points to),
if we are talking about FB's inline ASM. (Const makes it: "read only")
it's a ptr... the ptr is pointing to some, i would not be changing the ptr, but what it points to... (and thats fine)
and on inlined asm accessing [tA] works but again... [tA.a] does not :), which obviously can be calculated a compile time when its a global...
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: constant pointer to global struct member

Post by MrSwiss »

Mysoft wrote:it works with @tA but it does not work with @tA.A
Ptr access to member is -> (and not . ) therefore:

Code: Select all

asm
	mov (r)(e)ax, [ptA]	' load ptr 
	mov (r)(e)ax, [(r)(e)ax]	' load address (to type)
	...	' get offset to member
	...	' add offset to base address
	...	' load value
end asm
I don't know why you want to use assembly anyway ...

Lets for examples sake, stick to FB:

Code: Select all

' we want member A's value, from ptr: ptA
var x = ptA->A
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: constant pointer to global struct member

Post by MrSwiss »

If the aim is, to have only the ptr constant:

Code: Select all

type MyStruct
    as integer  A = 3456
end type

static shared as MyStruct tA
Dim Shared As MyStruct Const Ptr   ptA = @tA

Print ptA->A    ' outputs: 3456
ptA->A = 8912   ' new assignment
Print ptA->A    ' outputs: 8912

Sleep
The direct ptr to a member of a type, is not possible (indirect addressing only).
Mysoft
Posts: 836
Joined: Jul 28, 2005 13:56
Location: Brazil, Santa Catarina, Indaial (ouch!)
Contact:

Re: constant pointer to global struct member

Post by Mysoft »

MrSwiss wrote:
Mysoft wrote:it works with @tA but it does not work with @tA.A
Ptr access to member is -> (and not . )
@tA.A is not ptr access to member is address of the member of the struct i.e. @(tA.A) not (@tA).A ... so to get a constant (meaning its obtained at COMPILE TIME) that is the address to the member of the global UDT
Mysoft
Posts: 836
Joined: Jul 28, 2005 13:56
Location: Brazil, Santa Catarina, Indaial (ouch!)
Contact:

Re: constant pointer to global struct member

Post by Mysoft »

as an addendum... some examples

Code: Select all

type MyUDT
  A as integer
  B as integer
end type

static shared as MyUDT tTest

'ok this works...
static shared as MyUDT ptr pWork1 = @tTest

'*** this fails ****
'static shared as any ptr pFails1 = @(tTest.B)

'*** this ALSO fails ****
'static shared as test ptr pFail2 = cast(any ptr,@tTest)+offsetof(typeof(tTest),B)

'this Works, but has runtime addition 
dim as any ptr pWork2 = @(tTest.A)

#define Member( _T , _N ) _T+offsetof(typeof(_T),_N)

asm
  .global _pAddrOfB
  jmp 1f 'skip data inside code
  _pAddrOfB: .int tTest+offsetof(typeof(tTest),B) '<- this is a static shared constant as i wanted
  lea eax, [tTest+offsetof(typeof(tTest),B)] '<- also works
  mov eax, [tTest] 'this works
  'mov eax, [tTest.A] '<- this does not
  mov eax, [Member(tTest,A)] 'workaround of the previous
  1:
end asm

extern pAddrOfB alias "pAddrOfB" as any ptr '<- see combining with the asm one it works
print hex$(pAddrOfB,8)
print hex$(@tTest.B,8)
sleep
anyway its not that i need the ASM i was just saying that from ASM i can sorta workaround that, without the runtime overhead
for something that should have worked (altough may not the CONST... but at least initialize the address member, since ASM can do that
and accepting tTest.A on the asm block would be an improvement of the inlined asm integration... since thats freebasic ignoring the variable because of the . )
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: constant pointer to global struct member

Post by fxm »

Code: Select all

Type UDT
  Dim As Integer I = 123
  Dim As String s = "ABC"
  Dim As Double d = 3.14
End Type

Static Shared As UDT u

Static Shared As Integer Ptr pi
  pi = Cptr(Any Ptr, @u) + Offsetof(UDT,I)  '' or simply: pi = @u.I
Static Shared As String Ptr ps
  ps = Cptr(Any Ptr, @u) + Offsetof(UDT,s)  '' or simply: ps = @u.s
Static Shared As Double Ptr pd
  pd = Cptr(Any Ptr, @u) + Offsetof(UDT,d)  '' or simply: pd = @u.d

Print *pi
Print *ps
Print *pd

Sleep
Last edited by fxm on May 05, 2019 7:29, edited 1 time in total.
Mysoft
Posts: 836
Joined: Jul 28, 2005 13:56
Location: Brazil, Santa Catarina, Indaial (ouch!)
Contact:

Re: constant pointer to global struct member

Post by Mysoft »

fxm wrote:

Code: Select all

Type UDT
  Dim As Integer I = 123
  Dim As String s = "ABC"
  Dim As Double d = 3.14
End Type

Static Shared As UDT u

Static Shared As Integer Ptr pi
  pi = Cptr(Any Ptr, @u) + Offsetof(UDT,I)
Static Shared As String Ptr ps
  ps = Cptr(Any Ptr, @u) + Offsetof(UDT,s)
Static Shared As Double Ptr pd
  pd = Cptr(Any Ptr, @u) + Offsetof(UDT,d)

Print *pi
Print *ps
Print *pd

Sleep
true all that work but they are NOT constants and incurr runtime overhead that is not necessary... specially when the value is suppose to be avaliable at compile time as my combination of ASM and EXTERN showed....
Post Reply