SizeOf() shows size for non-existant instance?

BlitzMax Forums/BlitzMax Programming/SizeOf() shows size for non-existant instance?

ImaginaryHuman(Posted 2005) [#1]
Hey folks. I am getting a size back from SizeOf() when using it with an empty array. For example, I have two types, used something like this:

Type MyMainType
   Field MyArray:MySubType[]       'empty array, zero size
EndType

Type MySubType
   Field MyInt:Int
   Field MyFloat:Float
   Field MyString:String
End Type

Local MyTypes:MyMainType[100]       'array of MyMainType instances
MyTypes[0]=New MyMainType       'Create an instance at index 0
Print String(SizeOf(MyTypes[0].MyArray[0]))          'Print size of instance's array element

This will print the size of the MySubType type, ie 12. Shouldn't it be printing 0? I haven't even allocated space for the `myarray` array yet. MyTypes[0].MyArray=Null. Why does SizeOf() give a size, 12, as if there is an instance of MySubType there, when there isn't? Surely it'd make more sense for it to say 0 since the array is empty?

Print String(SizeOf(MyTypes[0].MyArray)) will print 0 - ie the array is empty, but if I point SizeOf to an element in that array (e.g. [0]) shouldn't it also say 0?

Or is this how it's meant to work (why?)

Thanks for feedback.


PowerPC603(Posted 2005) [#2]
My guess would be that
Print String(SizeOf(MyTypes[0].MyArray))

Print the size of the array, which currently has no pointers inside it, that's why it will print 0.

When you use
Print String(SizeOf(MyTypes[0].MyArray[0]))

BMax knows that the array's indexes will point to instances of the type-declaration "MySubType" and therefore it will print the size of the type-declaration, even when no instance has been created yet.

The type declaration MysubType would use 12 bytes, because an int uses 4 bytes, a float uses 4 bytes and the string also uses 4 bytes, because the MyString field is actually a pointer to a string-object, where a pointer is also an int.


Robert(Posted 2005) [#3]
In languages like C++ sizeof is a compile-time operator, which is replaced with a literal value representing the size of the type. Whether the instance is valid or not doesn't make any difference.


Floyd(Posted 2005) [#4]
The SizeOf operator can determine the size of something which changes at runtime.

But the size of something may make sense even if that thing does not exist.
For example, an Int is 4 bytes. So every element of an Int array is 4 bytes.
Local a:Int[] = New Int[ Rand( 5 ) ]

Print
Print SizeOf( a )

Print
Print SizeOf( a[0] )
Print SizeOf( a[9] )

Print
Print a[0]
Print a[9]
Here the size of the array is not known until the program runs. But the size of any element a[whatever] is 4 bytes.

With Debug On 'Print SizeOf( a[9] )' is an out of bounds error. It is still reasonable to say a[9] is 4 bytes even if those those bytes don't really belong to the array.


ImaginaryHuman(Posted 2005) [#5]
Ok, I guess these replies more or less sum it up, thanks!

I shall simpy remove the [0] from the expression to ensure I'm seeing runtime sizes rather than theoretical sizes.

Cheers.