What's the difference between PhantomData<T>
and [T; 0]
?
-
Technical aspect:
[T; 0]
currently requiresT : Sized
, and[T; 0]
has the alignment ofT
(whereasPhantomData
always has an alignment of1
).-
PhantomData<T>
also unconditionally isCopy + Debug + Ord + Hash
A tiny bonus for zero-long arrays is that they require no import or long name, and that instantiating one is very easy:
[]
. -
-
Documentation aspect:
PhantomData
may be a bit better at conveying that the stuff in question is "phantom", whereas an empty array, historically, is more often used for field/struct alignement shenanigans. -
My own rule of thumb:
I personally reach forPhantomData
when inside data types, and for[; 0]
when using it for function arguments, especially user-provided closure arguments when tinkering with higher-order signatures or whatnot (since the non-1
-alignment of a zero-sized parameter should play no role whatsoever in the machine code generated around function calls)
hah, funny you bring that up because that kind of stuff is exactly why we're playing with this XD (tho we can't seem to get it to work ourselves)
It does for the C abi on x86_64-pc-windows-gnu and {s390x,sparc64,powerpc}-unknown-linux-{gnu,musl,uclibc} I think. For some reason those platforms decided to not ignore zero sized arguments in their calling convention, so I think it will take up the amount of space a 1 byte sized type with the same alignment would.
Oh no
- Well, I'm still gonna assume or at least hope this doesn't happen for
extern "Rust"
/"rust-call"
-expanded closures
Indeed. For rust abi's ZST's are always ignored. In fact rustc itself depends on signatures of form extern "rust-call" fn(ZstType, (Arg1, Arg2))
to be abi compatible with those of from extern "Rust" fn(Arg1, Arg2)
. This allows it to cast from a closure that doesn't capture anything to a function pointer without needing a shim.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.