pull/106/head
Alexis Beingessner 6 years ago
parent 885c5bc5e7
commit 7f019ec5c8

@ -14,7 +14,7 @@ known size or alignment. On the surface, this is a bit nonsensical: Rust *must*
know the size and alignment of something in order to correctly work with it! In
this regard, DSTs are not normal types. Because they lack a statically known
size, these types can only exist behind a pointer. Any pointer to a
DST consequently becomes a *fat* pointer consisting of the pointer and the
DST consequently becomes a *wide* pointer consisting of the pointer and the
information that "completes" them (more on this below).
There are two major DSTs exposed by the language:
@ -67,6 +67,10 @@ fn main() {
}
```
(Yes, custom DSTs are a largely half-baked feature for now.)
# Zero Sized Types (ZSTs)
@ -157,11 +161,16 @@ because that wouldn't make sense.
We recommend against modelling C's `void*` type with `*const Void`.
A lot of people started doing that but quickly ran into trouble because
people want to convert raw pointers to references when doing FFI, and making an
`&Void` is Undefined Behaviour. `*const ()` (or equivalent) works just as well,
and can be made into a reference without any safety problems. The only downside
of modeling `void*` with `*const ()` is that attempts to read or write values
will silently succeed (doing nothing), instead of producing a compiler error.
Rust doesn't really have any safety guards against trying to instantiate
empty types with unsafe code, and if you do it, it's Undefined Behaviour.
This was especially problematic because developers had a habit of converting
raw pointers to references and `&Void` is *also* Undefined Behaviour to
construct.
`*const ()` (or equivalent) works reasonably well for `void*`, and can be made
into a reference without any safety problems. It still doesn't prevent you from
trying to read or write values, but at least it compiles to a no-op instead
of UB.

@ -29,7 +29,7 @@ passed through the FFI boundary.
C, and is explicitly contrary to the behavior of an empty type in C++, which
says they should still consume a byte of space.
* DST pointers (fat pointers) and tuples are not a concept
* DST pointers (wide pointers) and tuples are not a concept
in C, and as such are never FFI-safe.
* Enums with fields also aren't a concept in C or C++, but a valid bridging

@ -5,9 +5,11 @@ alignment of a type specifies what addresses are valid to store the value at. A
value with alignment `n` must only be stored at an address that is a multiple of
`n`. So alignment 2 means you must be stored at an even address, and 1 means
that you can be stored anywhere. Alignment is at least 1, and always a power
of 2. Most primitives are generally aligned to their size, although this is
platform-specific behavior. For example, on x86 `u64` and `f64` may be only
aligned to 4 (32 bits).
of 2.
Primitives are usually aligned to their size, although this is
platform-specific behavior. For example, on x86 `u64` and `f64` are often
aligned to 4 bytes (32 bits).
A type's size must always be a multiple of its alignment. This ensures that an
array of that type may always be indexed by offsetting by a multiple of its

Loading…
Cancel
Save