(SOLVED) different behavior (. ->)

General FreeBASIC programming questions.
Post Reply
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

(SOLVED) different behavior (. ->)

Post by VANYA »

Hi all!

Why code with the operator . (dot) does not behave as I expect this code:

Code: Select all

type AAA
	
	as Byte M(10)
	
End Type

type CLASSBB
	
	vData as AAA ptr ptr
	
	iSize as Long
	
	iRealMemSize as Long
	
	declare function push_back(vData as AAA ptr) as BOOLEAN
	
	Declare Operator [] (byref iIndex as Long) byref As AAA ptr
	
	Declare Operator let (byref v as AAA ptr)
	
End Type

function CLASSBB.push_back(vData as AAA ptr) as BOOLEAN
	
	if this.iSize >= this.iRealMemSize then
		
		this.iRealMemSize +=10
		
		this.vData =reallocate(this.vData , (this.iRealMemSize)* sizeof(AAA ptr))
		
		if this.vData =0 then
			
			return FALSE
			
		EndIf
		
	EndIf
	
	(this.vData)[iSize] =vData
	
	iSize +=1
	
	return TRUE
	
End Function

Operator CLASSBB.[] (byref iIndex as Long) byref As AAA ptr
	
	return (this.vData)[iIndex]
	
End Operator

function alloc() as AAA ptr
	
	dim p as AAA ptr = callocate(sizeof(AAA))
	
	? "real P=", p
	
	return p
	
End function


'example (wrong result)

dim v as CLASSBB

dim as AAA ptr p = alloc()

v.push_back(p) ' first pointers

v[0].M(0) = 1

p = alloc()

v.push_back(p) ' second pointers


v[0].M(0) = 2 

' print ponters

for i as Long = 0 to v.iSize-1
	
	? V[i] 
	
Next

sleep



RESULT:
'real P= 25522560 <-
'real P= 25527680
'25522434 <-
'25527680
However , if you replace the line with the operator . (dot)

Code: Select all

v[0].M(0) = 2 
to operator ->

Code: Select all

pTemp = v[0]

pTemp->M(0) = 2


then everything is fine:

Code: Select all

type AAA
	
	as Byte M(10)
	
End Type

type CLASSBB
	
	vData as AAA ptr ptr
	
	iSize as Long
	
	iRealMemSize as Long
	
	declare function push_back(vData as AAA ptr) as BOOLEAN
	
	Declare Operator [] (byref iIndex as Long) byref As AAA ptr
	
	Declare Operator let (byref v as AAA ptr)
	
End Type

function CLASSBB.push_back(vData as AAA ptr) as BOOLEAN
	
	if this.iSize >= this.iRealMemSize then
		
		this.iRealMemSize +=10
		
		this.vData =reallocate(this.vData , (this.iRealMemSize)* sizeof(AAA ptr))
		
		if this.vData =0 then
			
			return FALSE
			
		EndIf
		
	EndIf
	
	(this.vData)[iSize] =vData
	
	iSize +=1
	
	return TRUE
	
End Function

Operator CLASSBB.[] (byref iIndex as Long) byref As AAA ptr
	
	return (this.vData)[iIndex]
	
End Operator

function alloc() as AAA ptr
	
	dim p as AAA ptr = callocate(sizeof(AAA))
	
	? "real P=", p
	
	return p
	
End function


'example (good result)

dim v as CLASSBB

dim as AAA ptr p = alloc()

v.push_back(p) ' first pointers

dim as AAA ptr pTemp = v[0]

pTemp->M(0) = 1

p = alloc()

v.push_back(p) ' second pointers

pTemp = v[0]

pTemp->M(0) = 2 

' print ponters

for i as Long = 0 to v.iSize-1
	
	? V[i] 
	
Next

sleep

RESULT:
'real P= 10838400
'real P= 10843520
'10838400
'10843520
P.S. Linux 64 , last compiler
Last edited by VANYA on Mar 09, 2020 8:32, edited 1 time in total.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: different behavior (. ->)

Post by fxm »

The 'Operator [] (byref iIndex as Long) byref As AAA ptr' returns (by reference) a pointer to AAA.
Therefore, 'v[0]' returns a pointer to AAA.
'M(0)' is a member of AAA.
To access a UDT member from a UDT pointer, the operator '->' must be used ('v[0]->M(0) = 1' and 'v[0]->M(0) = 2')
(To access a UDT member from a UDT variable (or reference), the operator '.' must be used).

Otherwise, I don't know what the parser understand, but '(v[0])->M(0) = 1' and '(v[0])->M(0) = 2' work, while '(v[0]).M(0) = 1' and '(v[0]).M(0) = 2' don't work.
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: different behavior (. ->)

Post by VANYA »

Thank you fxm! You as always helped.

I just never seen such behaviour when the same code can be used simultaneously . and ->. So surprised, thought maybe some error in the behavior of the compiler. Now it is clear that in one case I write something that is at the address, and in the second case I rewrited address itself:

address = 1280000

data at address 1280000: 01010101010101010


CASE (->) address 1280000: 01010101010101010

CASE (.) address 1280000: 01010101010101010

By the way fxm , you kind of edit the documentation?! Example 2 from this page is incorrect (crashed):

Code: Select all

'' Use reference allows to simplify expressions compared to pointer
'' (avoid to use operator '@' and especially '*')


Dim As ZString Ptr pz = @"FreeBASIC Zstring Ptr"
Print *pz
*pz &= " 1.3.0"
Print *pz

Print

Dim ByRef As ZString rz = "FreeBASIC Zstring Ref"  '' or Var Byref rz = "FreeBASIC Zstring Ref"
Print rz
rz &= " 1.4.0"
Print rz

Sleep
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: different behavior (. ->)

Post by fxm »

Done:
KeyPgByrefVariables → fxm [Corrected the bugged example 2]
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: different behavior (. ->)

Post by VANYA »

fxm wrote:Done:
KeyPgByrefVariables → fxm [Corrected the bugged example 2]
Ok, thank you!
Post Reply