Type sizes and metadata

BlitzMax Forums/BlitzMax Programming/Type sizes and metadata

Czar Flavius(Posted 2011) [#1]
Let's say I have a type with an int. BlitzMax will report this as size 4. Let's say that I give this type a method, extend the type and override the method. C++ would give this type size 8 (32-bit), as an extra 4 bytes for a virtual function table pointer. I assume BlitzMax uses a similar construct, but the SizeOf size is still 4. Does this function return the size including metadata? If not, why not? As you couldn't then use it to allocate the necessary space so I don't understand its use.

Does a type which contains only data and no methods and takes no part in inheritance contain any extra metadata such as virtual pointers?

Last edited 2011


AdamRedwoods(Posted 2011) [#2]
My first guess is SizeOf is the SIZE of the TYPE-- but not the LENGTH of the type.... but yeah good point.
Have you tried putting more INTs in to see if the size goes up?

Edit:
Ah, here we go. Since SizeOf is run-time, perhaps the type hasn't been created yet in memory?
from:
http://blitzmax.com/Community/posts.php?topic=43508

Last edited 2011


Czar Flavius(Posted 2011) [#3]
Type base
	Field a:Int
End Type

Type der Extends base
	Field b:Int
End Type

Local arr:base[1]
arr[0] = New der
Print SizeOf(arr[0])
Print SizeOf(der)


This reports the size of arr[0] as 4 even though der is size 8, so I think it is computed at compile-time.

In C you can use sizeof in order to work out how much memory to allocate for a type. As memory management is automatic in BlitzMax, there isn't much use for this operator but if it doesn't report the memory-allocation size then it isn't much use for anything other than a curiosity or indication.


col(Posted 2011) [#4]
Hiya, i've done this in my directx code. I'm away for weekend at the moment so i'll check when I get back but ifrc when you make an instance of a type the instance will return the correct size. If you look at the dx9 cube mapping demo I posted, I also posted the source and I definately it use that technique to get the size of a custom vertex. Check it out for the correct solution to your problem.
I know it didn't return the size of an instance that would include any methods, but only included the size of the fields.
Also it may be different for arrays which may return the size that the array element is pointing to, ie 4 for a int or float array, 1 for byte array element etc.
Oh, and know it doesn't return the correct size if inherited, I agree it should but it doesn't. There are work arounds that pretty much make the inheritance completely redundant, but it can be done.




Last edited 2011

Last edited 2011


col(Posted 2011) [#5]
hiya Czar Flavius, home now....

this
Type parent
	Field base_x:int
	Field base_y:int
endtype

Type child Extends parent
	Field x:int
	Field y:int
	Field z:int
endtype

Print SizeOf(parent)
Print SizeOf(child)

Local grandma:parent = New parent
Local grandpa:child = New child

Print SizeOf(grandma)
Print SizeOf(grandpa)


prints out

8
20
8
20

on my machine.
Also i notice you are declaring the array with a type of the 'base' type, then you create the array element with the 'der' type. If you declare the array with the type of the 'der' type then you will get your expected result.

Last edited 2011


Czar Flavius(Posted 2011) [#6]
col, thanks for your code example but I think you have missed my question. It's not whether sizeof is resolved at compile or run time, but rather if types have any meta data added to them and if this is reported by sizeof or not.
Thanks.


col(Posted 2011) [#7]
Oops.
I did misinterpret your question.

And thank you for bringing this up about the metadata. Its useful to know either way.


AdamRedwoods(Posted 2011) [#8]
Ok, after poking around the BlitzMax source, I find that Types are basically Objects. So looking at the blitz_objects.c source:
Yes, there is internal metadata associated with types, and No, it is not reported by SizeOf.

I wouldn't use this test to get the actual size, BUT....
Type TInt
	Field x:Int
EndType

Type TVec
	Field x:Int
	Field y:Int
	Field z:Int
	
	Method Add(a:Int)
		x:+a
		y:+a
		z:+a
	EndMethod
EndType

GCCollect()

Local s:Int = GCMemAlloced()
Local j:TInt = New TInt

Print GCMemAlloced()-s+" bytes"

s:Int = GCMemAlloced()
Local mytest:TVec = New TVec

Print GCMemAlloced()-s+" bytes"

End


It *looks* like the base size is 8 bytes (from the source object class) which runs above as:
12 bytes
20 bytes

Process complete

so 12-8 = 4 (1 int), 20-8=12 (3 ints)

.

Last edited 2011


Czar Flavius(Posted 2011) [#9]
Aha, so the metadata is always 8 bytes! Maybe?

I'm guessing that 4 bytes is for the virtual pointer and 4 bytes is for the GC reference counting.

http://en.wikipedia.org/wiki/Virtual_method_table
http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29#Reference_counting

Last edited 2011


AdamRedwoods(Posted 2011) [#10]
I think it depends on the garbage collector you're using. If you check 'Threaded Build' it uses another type of gc.
I would say use it at your own risk.