This came up while experimenting with @flaggify and @bitfieldify from FieldFlags.jl (name pending).
julia> primitive type Foo_prim 40 end
julia> struct Foo_p
a::Foo_prim
end
julia> struct Foo
a::NTuple{5, UInt8}
end
julia> sizeof(Foo_prim)
5
julia> sizeof(Foo_p)
8
julia> sizeof(NTuple{5, UInt8})
5
julia> sizeof(Foo)
5
julia> Base.datatype_haspadding(NTuple{5, UInt8})
false
julia> Base.datatype_haspadding(Foo)
false
julia> Base.datatype_haspadding(Foo_prim)
false
julia> Base.datatype_haspadding(Foo_p)
false # ?!
How can Foo_p grow in size from 5 to 8 bytes, when there isn't supposed to be any padding there?
Additionally, Base.padding doesn't seem to take this "magic end-struct padding" into account, not even for structs that do claim to have padding:
julia> sizeof(Tuple{UInt32, UInt8})
8
julia> Base.datatype_haspadding(Tuple{UInt32, UInt8})
true
julia> Base.padding(Tuple{UInt32, UInt8})
Base.Padding[] # ?!
julia> Base.padding(Foo_p)
Base.Padding[]
So either Foo_p doesn't have padding, which begs the question why it's 8 bytes in size, or it does, which begs the question why it claims that it doesn't.
This came up while experimenting with
@flaggifyand@bitfieldifyfrom FieldFlags.jl (name pending).How can
Foo_pgrow in size from 5 to 8 bytes, when there isn't supposed to be any padding there?Additionally,
Base.paddingdoesn't seem to take this "magic end-struct padding" into account, not even for structs that do claim to have padding:So either
Foo_pdoesn't have padding, which begs the question why it's 8 bytes in size, or it does, which begs the question why it claims that it doesn't.