Size of immutables


#1

Why is sizeof(M.C) larger than the others? Tested with 0.5.0, 0.4.7 and 0.6.0-dev.2525.

julia> module M
       immutable A
           e::UInt32
           a::UInt32
           b::UInt64
       end
       immutable B
           e::UInt64
           a::UInt32
           b::UInt32
       end
       immutable C
           a::UInt32
           e::UInt64
           c::UInt32
       end
       immutable D
           a::UInt32
           c::UInt32
           e::UInt64
       end
       immutable E
           a::UInt64
           e::UInt64
       end
       end
M

julia> sizeof(M.A)
16

julia> sizeof(M.B)
16

julia> sizeof(M.C)
24

julia> sizeof(M.D)
16

julia> sizeof(M.E)
16


#2

Alignment. <20 char limit>


#3

what happens, if I do something like read(mystream, M.C) vs. read(mystream, M.B), how many bytes are read?


#4

sizeof(T) bytes. And it’ll be platform dependent.


#5

so on my testing computer 8 bytes will get swallowed if i do my_c = read(mystream, M.C)


#6

Just to be clear, this is not unique to Julia. This is the same as what would happen if you declared a C struct with those types: the compiler adds padding inside the struct to make sure that data is properly aligned.

See e.g. data structure alignment on wikipedia or this article on struct packing or this stackoverflow thread.

The fact that Julia properly aligns structure members like this is important for performance, and for calling C libraries.

If you want to read non-aligned binary data from a file, just use read. e.g. C(read(f,UInt32), read(f, UInt64), read(f, UInt32)). (Of course, for file i/o, you may also need to worry about endianness issues: you might want to call ntoh on the result of the read.)


#7

In principle correct. Do we actually have that method?


#8

ok, thank you, that was a very clear answer!


#9

for the sake of completeness:

  ntoh(x)

  Converts the endianness of a value from Network byte
  order (big-endian) to that used by the Host.