@@ -12,28 +12,42 @@ to have the same size. The ways to cause Undefined Behavior with this are mind
12
12
boggling.
13
13
14
14
* First and foremost, creating an instance of * any* type with an invalid state
15
- is going to cause arbitrary chaos that can't really be predicted.
15
+ is going to cause arbitrary chaos that can't really be predicted. Do not
16
+ transmute ` 3 ` to ` bool ` . Even if you never * do* anything with the ` bool ` . Just
17
+ don't.
16
18
* Transmute has an overloaded return type. If you do not specify the return type
17
19
it may produce a surprising type to satisfy inference.
18
- * Making a primitive with an invalid value is UB
19
- * Transmuting between non-repr(C) types is UB
20
- * Transmuting an & to &mut is UB
21
- * Transmuting an & to &mut is * always* UB
22
- * No you can't do it
23
- * No you're not special
20
+ * Transmuting an & to &mut is UB.
21
+ * Transmuting an & to &mut is * always* UB.
22
+ * No you can't do it.
23
+ * No you're not special.
24
24
* Transmuting to a reference without an explicitly provided lifetime
25
25
produces an [ unbounded lifetime]
26
+ * When transmuting between different compound types, you have to make sure they
27
+ are laid out the same way! If layouts differ, the wrong fields are going to
28
+ get filled with the wrong data, which will make you unhappy and can also be UB
29
+ (see above).
30
+
31
+ So how do you know if the layouts are the same? For ` repr(C) ` types and
32
+ ` repr(transparent) ` types, layout is precisely defined. But for your
33
+ run-of-the-mill ` repr(Rust) ` , it is not. Even different instances of the same
34
+ generic type can have wildly different layout. ` Vec<i32> ` and ` Vec<u32> `
35
+ * might* have their fields in the same order, or they might not. The details of
36
+ what exactly is and is not guaranteed for data layout are still being worked
37
+ out over [ at the UCG WG] [ ucg-layout ] .
26
38
27
39
[ ` mem::transmute_copy<T, U> ` ] [ transmute_copy ] somehow manages to be * even more*
28
40
wildly unsafe than this. It copies ` size_of<U> ` bytes out of an ` &T ` and
29
41
interprets them as a ` U ` . The size check that ` mem::transmute ` has is gone (as
30
42
it may be valid to copy out a prefix), though it is Undefined Behavior for ` U `
31
43
to be larger than ` T ` .
32
44
33
- Also of course you can get most of the functionality of these functions using
34
- pointer casts.
45
+ Also of course you can get all of the functionality of these functions using raw
46
+ pointer casts or ` union ` s, but without any of the lints or other basic sanity
47
+ checks. Raw pointer casts and ` union ` s do not magically avoid the above rules.
35
48
36
49
37
50
[ unbounded lifetime ] : unbounded-lifetimes.html
38
51
[ transmute ] : ../std/mem/fn.transmute.html
39
52
[ transmute_copy ] : ../std/mem/fn.transmute_copy.html
53
+ [ ucg-layout ] : https://rust-lang.github.io/unsafe-code-guidelines/layout.html
0 commit comments