primitive types currently round to the byte for storage:
julia> primitive type Int24 <: Integer 24 end
julia> Base.datatype_alignment(Int24)
4
julia> Core.sizeof(Int24)
3
julia> Base.aligned_sizeof(Int24)
4
The result is that we have three notions of "sizeof" in Julia, analogous to LLVM:
There's also a performance trade-off associated with this quirk. If Core.sizeof is not aligned, a Ptr{Int24} must be read / written with a multiple 16- / 8-bit operations, instead of a single 32-bit load / store.
We should consider re-aligning with C23 and making the Core.sizeof aligned (i.e. Core.sizeof(T) == Base.aligned_sizeof(T::DataType)), like it is for every other type in the system. IMO most uses fall squarely into the "packed data" camp (so request the bit size and round up to the byte if you need to) or the "normal allocation" camp (so use Base.aligned_sizeof).
The fact that Core.sizeof is not the allocation size is a somewhat frequent source of confusion, and I've encountered multiple bugs in the wild related to Core.sizeof being used where Base.aligned_sizeof is the right choice.
primitivetypes currently round to the byte for storage:The result is that we have three notions of "sizeof" in Julia, analogous to LLVM:
Core.sizeofin Julia,getTypeStoreSize()in LLVMBase.aligned_sizeofin Julia,getTypeAllocSize()in LLVMCore.bitsizeofas proposed in core: support odd-bit primitive integers, add Core.bitsizeof #61359,getTypeSizeInBits()in LLVMThere's also a performance trade-off associated with this quirk. If
Core.sizeofis not aligned, aPtr{Int24}must be read / written with a multiple 16- / 8-bit operations, instead of a single 32-bit load / store.We should consider re-aligning with C23 and making the
Core.sizeofaligned (i.e.Core.sizeof(T) == Base.aligned_sizeof(T::DataType)), like it is for every other type in the system. IMO most uses fall squarely into the "packed data" camp (so request the bit size and round up to the byte if you need to) or the "normal allocation" camp (so useBase.aligned_sizeof).The fact that
Core.sizeofis not the allocation size is a somewhat frequent source of confusion, and I've encountered multiple bugs in the wild related toCore.sizeofbeing used whereBase.aligned_sizeofis the right choice.