UDT = UDT

New to FreeBASIC? Post your questions here.
Post Reply
speedfixer
Posts: 606
Joined: Nov 28, 2012 1:27
Location: CA, USA moving to WA, USA
Contact:

UDT = UDT

Post by speedfixer »

This is (some flavor of) BASIC. Things should be simple.

Code: Select all

' assign test

type ttest
    fname as string
    age as integer
    bbb as double
end type

dim as ttest aa(3), bb(3)

aa(1).fname = "david"
aa(1).age = 63
aa(1).bbb = 1.234

bb() = aa()
bb = aa
I use types to keep my data groups together. Basic data types, nothing complex. I DON'T want to have to make constructors and destructors. That's for c, c++ and the other 'hard' languages.

How can I make the above work . . simply ? There has to be a way.

david
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Re: UDT = UDT

Post by MichaelW »

At least within limits, you can do it with the CRT memcpy function.

Code: Select all

#include "crt.bi"

type ttest
    fname as string
    age as integer
    bbb as double
end type

dim as ttest aa(3), bb(3)

aa(0).fname = "david"
aa(0).age = 63
aa(0).bbb = 1.234
aa(3).fname = "dufus"
aa(3).age = 19
aa(3).bbb = 3.14159

'bb() = aa()
'bb = aa

print aa(0).fname, aa(0).age, aa(0).bbb
print aa(3).fname, aa(3).age, aa(3).bbb
print bb(0).fname, bb(0).age, bb(0).bbb
print bb(3).fname, bb(3).age, bb(3).bbb

print sizeof(ttest)
print sizeof (aa)
print sizeof (bb)

memcpy(@bb(0),@aa(0),sizeof(aa)*4)

print aa(0).fname, aa(0).age, aa(0).bbb
print aa(3).fname, aa(3).age, aa(3).bbb
print bb(0).fname, bb(0).age, bb(0).bbb
print bb(3).fname, bb(3).age, bb(3).bbb

sleep

Code: Select all

david          63            1.234
dufus          19            3.14159
               0             0
               0             0
 40
 40
 40
david          63            1.234
dufus          19            3.14159
david          63            1.234
dufus          19            3.14159
sancho2
Posts: 547
Joined: May 17, 2015 6:41

Re: UDT = UDT

Post by sancho2 »

speedfixer wrote:This is (some flavor of) BASIC. Things should be simple.
I use types to keep my data groups together. Basic data types, nothing complex. I DON'T want to have to make constructors and destructors. That's for c, c++ and the other 'hard' languages.
How can I make the above work . . simply ? There has to be a way.
david
You are not failing to copy the contents of one user defined type to another. You are failing to copy one array to another.
Consider that the following does copy:

Code: Select all

Type test
	a As Integer
	b As Integer
End Type

Dim n As test
Dim r As test
n.a = 12
n.b = 13

r = n
Print r.a, r.b

Sleep
It is unreasonable to limit yourself by avoiding programming constructs that may present a solution. Constructors are easy, however they will not help you copy arrays. At least not directly.
speedfixer
Posts: 606
Joined: Nov 28, 2012 1:27
Location: CA, USA moving to WA, USA
Contact:

Re: UDT = UDT

Post by speedfixer »

Thank you, each, for the effort of your reply.

@sancho2:
sure - but it won't work with an array - and strings present even more trouble.

@MichaelW:
Needing to step outside of FB suggests to me that something is missing.

Problem solved, though.
I can make my own copy function: roll through a third object of the same type. Slow, but works.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: UDT = UDT

Post by Tourist Trap »

sancho2 wrote:It is unreasonable to limit yourself by avoiding programming constructs that may present a solution. Constructors are easy, however they will not help you copy arrays. At least not directly.
I think the problem is not the constructor, which you don't need defining explicitely if you don't need to construct your object in another manner than just assigning default values.

You are right pointing out that the array can't be assigned one each others. And even the operator LET would fail doing this for the moment. It's a current limitation that has been discussed with fxm recently.
fxm wrote:Look at the feature request:
#285 Let overloads should support array parameters
So copying the array field will have to be performed manually (index by index) or everything washed out via a memcopy like also pointed out. Defining a constructor is always possible, but as I see this personnally, it would be more a workaround here, and probably would be solved in the future.
dkl
Site Admin
Posts: 3235
Joined: Jul 28, 2005 14:45
Location: Germany

Re: UDT = UDT

Post by dkl »

Since the support for dynamic array fields was added, FB has some internal support for copying arrays too (it was needed to implement the implicit Let overloads for that case). So allowing assignments like array1 = array2 would probably be easy.

A plain memcpy() isn't enough if Strings are involved though, due to their dynamic buffers that must be duplicated properly.
MOD
Posts: 557
Joined: Jun 11, 2009 20:15

Re: UDT = UDT

Post by MOD »

I guess the best way for deep copying ist to serialize and deserialize objects. In FB it isn't that easy. I tried to find my way for lists and maps in mdCollectionsHelper.
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: UDT = UDT

Post by fxm »

dkl wrote:Since the support for dynamic array fields was added, FB has some internal support for copying arrays too (it was needed to implement the implicit Let overloads for that case).
So another workaround in the pure FreeBASIC is to pack a dynamic array of this type in an UDT:

Code: Select all

type ttest
    fname as string
    age as integer
    bbb as double
end type

type ttestArray
    dim array(any) as ttest
end type

dim as ttestArray aa, bb
redim aa.array(3)
aa.array(1).fname = "david"
aa.array(1).age = 63
aa.array(1).bbb = 1.234

bb = aa
Print bb.array(1).fname
Print bb.array(1).age
Print bb.array(1).bbb

Sleep

Code: Select all

david
 63
 1.234
speedfixer
Posts: 606
Joined: Nov 28, 2012 1:27
Location: CA, USA moving to WA, USA
Contact:

Re: UDT = UDT

Post by speedfixer »

Excellent!

That is a much more elegant solution than what I did.

I will have to do some testing.
Thank you.

david
speedfixer
Posts: 606
Joined: Nov 28, 2012 1:27
Location: CA, USA moving to WA, USA
Contact:

Re: UDT = UDT

Post by speedfixer »

Thank you, fxm.
Your routine is about 10% faster than my solution.

I appreciate the problems a UDT has with non-fixed length strings and attempts at cross-assignment.

That aside . . .


For my original code that I posted, the error messages are:

Code: Select all

test.bas(14) error 10: Expected '=', found '(' in 'bb() = aa()'
test.bas(15) error 72: Array access, index expected, before '=' in 'bb = aa'
Either error points in the wrong direction when trying to fix the problem.
Without knowledge that can only be picked up by extensive reading of the forums, and lots of practical experience looking for problems, a person would never have a hint of the problem.

How can that be corrected in the documents?

And I bow to fxm's greater experience and patience at searching for a solution, but how could anyone else ever arrive at his solution by following the documentation?

** my suggestion **

Perhaps there could be an errata and caveats page that describes the broken functions (like LOCK), the gothcha's (variable names that look like asm register names), and quirks (like extra mandatory () around ... still have no idea when ...) that only years of experience can overcome. Add little snippets that display behavior that is or seems contradictory to the documentation.

Not everyone has the patience to stick around long enough to appreciate FB's power. A few bad experiences - and they are gone. FB *barely* has enough users now to keep it alive for the ages.

david

and maybe this should be moved/split/copied to general discussion
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: UDT = UDT

Post by fxm »

dkl wrote:Since the support for dynamic array fields was added, FB has some internal support for copying arrays too (it was needed to implement the implicit Let overloads for that case).
I have noticed that in the case of implicit Let overload for dynamic array members, some code is also added if compiling with option '-exx', while it is not necessary to test the array bounds because by principle the destination array is first resized with respect to the source array.

Is that optimization is possible?
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: UDT = UDT

Post by Tourist Trap »

dkl wrote: So allowing assignments like array1 = array2 would probably be easy.
It would be a nice addition at least for arrays equally dimensionned. Maybe featuring assignation for more complex cases (or totally custom) could then be a task for some LET operator overload. Unfortunately for the moment LET with arrays is dysfunctionning .
MOD wrote:I guess the best way for deep copying ist to serialize and deserialize objects. In FB it isn't that easy. I tried to find my way for lists and maps in mdCollectionsHelper.
I'm myself trying (at my level) doing some variable tracking by address, to manage copy assignation (or prevent it in fact). I won't say more here since it goes out of topic, but I was thinking that *LET to multiples variables* seems containing a mechanism of field type checking and even order checking. Couldn't this help for serializing an udt? I mean more precisely that if you know the order of the field and their type, you can stringuify accordingly.
Post Reply