Hacker News new | ask | show | jobs
by a1369209993 2311 days ago
> On the rust side, it's that, plus the pointer must point to a valid region of memory (non-null) even if the slice is empty.

Do you have a citation for that, because it seems obviously wrong[0] (since the slice points to zero bytes of memory) and I'm having trouble coming up with any situation that would justify it (except possibly using a NULL pointer to indicate the Nothing case of a Maybe<Slice> datum)?

0: by which I mean that Rust is wrong to require that, not that you're wrong about what Rust requires.

1 comments

Well the docs have this to say [1]:

`data` must be non-null and aligned even for zero-length slices. One reason for this is that enum layout optimizations may rely on references (including slices of any length) being aligned and non-null to distinguish them from other data. You can obtain a pointer that is usable as data for zero-length slices using NonNull::dangling().

So yes, this requirement allows optimizations like having Option<&[T]> be the same size as &[T] (I just tested and this is the case today: both are the same size).

I'm not convinced that it's "wrong", though. If you want to be able to support slices of zero elements (without using an option/maybe type) you have to put something in the pointer field. C generally chooses NULL, Rust happens to choose a different value. But they're both somewhat arbitrary values. It's not immediately obvious to me that one is a better choice than the other.

[1] https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html

> [1] https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html

Thanks.

> having Option<&[T]> be the same size as &[T]

That is literally what I mentioned as a possible reason ("except possibly ..."), but what I overlooked was that you could take a mutable reference to the &[T] inside a Option<&[T]>, then store a valid &[T] into it - if NULL is allowed, you effectively mutated the discriminant of a enum when you have active references to its fields, violating some aspect of type/memory safety, even I'm not sure which.

> C generally chooses NULL, Rust happens to choose a different value.

It's not about what pointer value the langauge chooses when it's asked to create a zero-length slice, it's about whether the language accepts a NULL pointer in a zero-length slice it finds lying around somewhere.