From 3050c357a792d7253f0070cb62b1fbf86fc4ea29 Mon Sep 17 00:00:00 2001 From: nomicon-kr Date: Wed, 25 Sep 2024 23:51:18 +0900 Subject: [PATCH] Update transmutes.md --- src/transmutes.md | 58 ++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 36 deletions(-) diff --git a/src/transmutes.md b/src/transmutes.md index 76ab634..811d648 100644 --- a/src/transmutes.md +++ b/src/transmutes.md @@ -1,39 +1,25 @@ # 변질 -Get out of our way type system! We're going to reinterpret these bits or die -trying! Even though this book is all about doing things that are unsafe, I -really can't emphasize enough that you should deeply think about finding Another Way -than the operations covered in this section. This is really, truly, the most -horribly unsafe thing you can do in Rust. The guardrails here are dental floss. - -[`mem::transmute`][transmute] takes a value of type `T` and reinterprets -it to have type `U`. The only restriction is that the `T` and `U` are verified -to have the same size. The ways to cause Undefined Behavior with this are mind -boggling. - -* First and foremost, creating an instance of *any* type with an invalid state - is going to cause arbitrary chaos that can't really be predicted. Do not - transmute `3` to `bool`. Even if you never *do* anything with the `bool`. Just - don't. - -* Transmute has an overloaded return type. If you do not specify the return type - it may produce a surprising type to satisfy inference. - -* Transmuting an `&` to `&mut` is Undefined Behavior. While certain usages may - *appear* safe, note that the Rust optimizer is free to assume that a shared - reference won't change through its lifetime and thus such transmutation will - run afoul of those assumptions. So: - * Transmuting an `&` to `&mut` is *always* Undefined Behavior. - * No you can't do it. - * No you're not special. - -* Transmuting to a reference without an explicitly provided lifetime - produces an [unbounded lifetime]. - -* When transmuting between different compound types, you have to make sure they - are laid out the same way! If layouts differ, the wrong fields are going to - get filled with the wrong data, which will make you unhappy and can also be - Undefined Behavior (see above). +저리 비켜 타입 시스템! 우린 이 비트들을 재해석하거나 죽을 것이다! 비록 이 책이 불안전한 것들을 하는 것에 대한 내용이지만, 이 섹션에 소개된 내용 말고 **다른 방법을** 깊게 생각해 봐야 한다고 충분히 강조할 수가 없네요. +이것은 진짜, 진실로, 러스트에서 할 수 있는 가장 끔찍하게 불안전한 것입니다. The guardrails here are dental floss. + +[`mem::transmute`][transmute]는 `T` 타입의 값을 받아서 `U` 타입의 값이 되도록 재해석합니다. 유일한 제한은 `T`와 `U`가 같은 크기를 가지는 것이 보장되어야 한다는 겁니다. +이것으로 미정의 동작을 일으키는 방법들은 충격적입니다. + +* 첫번째로, 그리고 가장 중요하게 말할 것은, *어떤* 타입의 값이든 올바르지 않은 상태로 만드는 것은 정말로 예상할 수 없는 변덕스러운 혼돈을 초래할 것입니다. `3`을 `bool`로 변질하지 마세요. 그 `bool`로 *아무것도* 하지 않더라도요. 그냥 하지 마세요. + +* 변질은 반환 타입이 타입 변수입니다. 만약 반환 타입을 명시하지 않는다면 타입 추론을 만족하기 위해 이상한 타입을 반환할 수 있습니다. + +* `&`를 `&mut`로 변질하는 것은 **미정의 동작입니다**. 이것을 사용하는 몇몇 부분이 안전하게 *보일 수* 있지만, 러스트가 최적화를 할 때 불변 레퍼런스는 그 수명 동안 변하지 않는다는 것이라 가정하고, 이런 변질은 그런 가정과 정면으로 충돌할 수 있다는 것을 주의하세요. 따라서: + * `&`를 `&mut`로 변질하는 것은 *언제나* **미정의 동작입니다**. + * 안됩니다, 하면 안돼요. + * 아뇨, 당신은 특별하지 않습니다. + +* 레퍼런스로 변질할 때 명확히 수명을 제시하지 않으면 [무제한 수명이][unbounded lifetime] 됩니다. + +* 서로 다른 복합 타입들 간에 변질할 때, 타입들이 똑같이 정렬되어 있다는 것을 확실히 해야 합니다! 만약 다르게 정렬되어 있다면, 잘못된 필드가 잘못된 값으로 채워지고, 그러면 당신을 불행하게 만들고 또한 **미정의 동작이** 발생할 수 있습니다 (위를 보세요). + + 그럼 똑같이 정렬되어 있는지 어떻게 알까요? So how do you know if the layouts are the same? For `repr(C)` types and `repr(transparent)` types, layout is precisely defined. But for your @@ -54,6 +40,6 @@ pointer casts or `union`s, but without any of the lints or other basic sanity checks. Raw pointer casts and `union`s do not magically avoid the above rules. [unbounded lifetime]: ./unbounded-lifetimes.md -[transmute]: ../std/mem/fn.transmute.html -[transmute_copy]: ../std/mem/fn.transmute_copy.html +[transmute]: https://doc.rust-lang.org/std/mem/fn.transmute.html +[transmute_copy]: https://doc.rust-lang.org/std/mem/fn.transmute_copy.html [ucg-layout]: https://rust-lang.github.io/unsafe-code-guidelines/layout.html