Why doesn't this crash (UDT copy)

General FreeBASIC programming questions.
Post Reply
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Why doesn't this crash (UDT copy)

Post by badidea »

I have a piece of code that looks like this. I works fine, but I do not trust it. Is this code fine or unsafe?
When I do 'poly(1) = poly(0)' when/how/who/what allocates memory for the 'points' array of 'poly(1)'?

Code: Select all

type sgl2d
	dim as single x, y
end type

type polygon
	redim as sgl2d points(any)
	declare destructor()
	declare sub init()
end type

destructor polygon()
	print "destructor polygon() @ "; hex(@this)
	print "points @ "; hex(@points(0))
	print "bounds:"; lbound(points); ubound(points)
	print
	erase(points)
end destructor

sub polygon.init()
	redim points(0 to 2)
	points(0).x = 123 : points(0).y = 456
end sub

dim as polygon poly(0 to 1)

poly(0).init()
poly(1) = poly(0) '<--- Why does this work? How is memory allocated for points?
poly(1).destructor()
poly(1) = poly(0) '<-- Let's try again

print poly(1).points(0).x, poly(1).points(0).y
print

print "Program exit"
print
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Why doesn't this crash (UDT copy)

Post by MrSwiss »

The code is safe, but very sploppy coding ...
What I mean above is:
you always omit the "This" specifier before the types member access, which
makes code harder to read, too.

Recoded version (see: comments added):

Code: Select all

type sgl2d
   dim as single x, y
end type

type polygon
    As sgl2d points(any)
    Declare destructor()
    Declare sub init()
end type

destructor polygon()
    Print "destructor polygon() @ "; hex(@This)
    Print "points @ "; hex(@This.points(0))
    Print "bounds:"; lbound(This.points); ubound(This.points)
    Print
    Erase(points)
end destructor

sub polygon.init()
    ReDim This.points(0 to 2)   ' <--- memory allocated for points
    This.points(0).x = 123
    This.points(0).y = 456
End sub

dim as polygon poly(0 to 1)

poly(0).init()      ' below works because of this!!!
poly(1) = poly(0) '<--- Why does this work? How is memory allocated for points?
poly(1).destructor()
poly(1) = poly(0) '<-- Let's try again

print poly(1).points(0).x, poly(1).points(0).y
print

print "Program exit"
print
sleep
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Why doesn't this crash (UDT copy)

Post by fxm »

@MrSwiss,
  • There is one 'This' missing ! :-)
    Erase(This.points)
    (but I do not criticize your remark: I, too, always precise 'This.' in the member procedures)
@badidea,
(more seriously)
  • For UDT containing a dynamic array as a member field, the implicit Let operator:
    - Size the dynamic array of the left-hand operand as that of the right-hand operand ([re]sizing or erasing).
    - Then copy all elements (if sized).

    Note: Obviously if you define your own overload Let operator, it's up to you to code all this in your own operator's body.

    See the Type documentation page:
    .....
    Variable-length data
    In FreeBASIC, Type data structures must ultimately be fixed-size, such that the compiler knows how much memory to allocate for objects of that Type. Nevertheless, Types may contain variable-length (dynamic) string or array data members. However, the string's/array's data will not be embedded in the Type directly. Instead, the Type will only contain a String/array descriptor structure, which FreeBASIC uses behind the scenes to manage the variable-length string/array data. For sizing the structure of the array descriptor in the Type, a variable-length (dynamic) array data member must be always declared by using Any(S) in place of the array bounds, in order to fix the amount of dimensions based on the number of Anys specified.
    Variable-length array fields are considered as pseudo-objects when they are declared in a Type, just like variable-length strings (the implicit copy constructor and the implicit let operator themselves support [re]sizing and copying such arrays, or their erasing).
    .....
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Why doesn't this crash (UDT copy)

Post by badidea »

fxm wrote:
...the implicit copy constructor and the implicit let operator themselves support [re]sizing and copying such arrays, or their erasing)...
Thanks, the compiler is more advanced than I expected :-)
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Why doesn't this crash (UDT copy)

Post by fxm »

badidea wrote:Thanks, the compiler is more advanced than I expected :-)
We must thank dkl.
Post Reply