Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Sizes

Every type occupies a fixed number of bytes, and sizeof reports it. Most of the time you do not need the number, but it matters when you read binary data, call C code, or keep a large array of records in memory.

'' sizeof( T ) is the size of a type in bytes; sizeof( x ) is the size
'' of a value's type. len( T ) means the same for a type.
print "sizeof( int16 ) ="; sizeof( int16 ); ", len( int16 ) ="; len( int16 )
print "sizeof( float64 ) ="; sizeof( float64 )

'' integer and pointers are as wide as an address on the target.
print "sizeof( integer ) ="; sizeof( integer ); _
      ", sizeof( any ptr ) ="; sizeof( any ptr )

'' For text, len( s ) is the number of characters; sizeof( s ) is the
'' fixed size of the ustring value itself, whatever it holds.
dim as ustring shortText = "hi"
dim as ustring longText = "a much longer piece of text"
print "len:"; len( shortText ); len( longText ); _
      ", sizeof:"; sizeof( shortText ); sizeof( longText )

'' A record is at least the sum of its fields. Each field sits at a
'' multiple of its own size, so the order of the fields matters.
type Loose
    as uint8 flag
    as int32 value
    as uint8 mark
end type
type Tight
    as int32 value
    as uint8 flag
    as uint8 mark
end type
print "Loose: sizeof"; sizeof( Loose ); ", value at offset"; _
      offsetof( Loose, value ); ", mark at"; offsetof( Loose, mark )
print "Tight: sizeof"; sizeof( Tight ); ", value at offset"; _
      offsetof( Tight, value ); ", mark at"; offsetof( Tight, mark )

Output

sizeof( int16 ) = 2, len( int16 ) = 2
sizeof( float64 ) = 8
sizeof( integer ) = 8, sizeof( any ptr ) = 8
len: 2 27, sizeof: 24 24
Loose: sizeof 12, value at offset 4, mark at 8
Tight: sizeof 8, value at offset 0, mark at 5

sizeof takes a type or a value. len given a type means the same thing; given text, it means the number of characters.

integer and pointers have the width of an address: 8 bytes on both 64-bit targets. Use the fixed-width names (int32, int64) when the width matters and integer when a value has to match the machine's word, such as an index into something very large.

A ustring variable is a fixed-size value that manages its text elsewhere, so sizeof is the same for short and long text. len is the one that changes.

A record's fields are laid out in order, each at an offset that is a multiple of its own size, and the whole record is rounded up to a multiple of its largest field. Loose puts a 1-byte field before a 4-byte one, so three bytes of padding go in between and the record takes 12 bytes. Tight has the same fields largest first and takes 8. offsetof( T, field ) shows where each field starts.

Activities

  1. Add an int64 field to the end of Tight and predict its sizeof before you run it.
  2. Print sizeof( Loose ) * 1000000 and sizeof( Tight ) * 1000000: the memory an array of a million of each would take.