변질

저리 비켜 타입 시스템! 우린 이 비트들을 재해석하거나 죽을 것이다! 비록 이 책이 불안전한 것들을 하는 것에 대한 내용이지만, 이 섹션에 소개된 내용 말고 다른 방법을 깊게 생각해 봐야 한다고 충분히 강조할 수가 없네요. 이것은 진짜, 진실로, 러스트에서 할 수 있는 가장 끔찍하게 불안전한 것입니다. 여기 있는 글들은 단지 치실 같은 역할일 뿐입니다.

mem::transmute<T, U>T 타입의 값을 받아서 U 타입의 값이 되도록 재해석합니다. 유일한 제한은 TU가 같은 크기를 가지는 것이 보장되어야 한다는 겁니다. 이것으로 미정의 동작을 일으키는 방법들은 충격적입니다.

  • 첫번째로, 그리고 가장 중요하게 말할 것은, 어떤 타입의 값이든 올바르지 않은 상태로 만드는 것은 정말로 예상할 수 없는 변덕스러운 혼돈을 초래할 것입니다. 3bool로 변질하지 마세요. 그 bool아무것도 하지 않더라도요. 그냥 하지 마세요.

  • 변질은 반환 타입이 타입 변수입니다. 만약 반환 타입을 명시하지 않는다면 타입 추론을 만족하기 위해 이상한 타입을 반환할 수 있습니다.

  • &&mut로 변질하는 것은 미정의 동작입니다. 이것을 사용하는 몇몇 부분이 안전하게 보일 수 있지만, 러스트가 최적화를 할 때 불변 레퍼런스는 그 수명 동안 변하지 않는다는 것이라 가정하고, 이런 변질은 그런 가정과 정면으로 충돌할 수 있다는 것을 주의하세요. 따라서:

    • &&mut로 변질하는 것은 언제나 미정의 동작입니다.
    • 안됩니다, 하면 안돼요.
    • 아뇨, 당신은 특별하지 않습니다.
  • 레퍼런스로 변질할 때 명확히 수명을 제시하지 않으면 무제한 수명이 됩니다.

  • 서로 다른 복합 타입들 간에 변질할 때, 타입들이 똑같이 정렬되어 있다는 것을 확실히 해야 합니다! 만약 다르게 정렬되어 있다면, 잘못된 필드가 잘못된 값으로 채워지고, 그러면 당신을 불행하게 만들고 또한 미정의 동작이 발생할 수 있습니다 (위를 보세요).

    그럼 똑같이 정렬되어 있는지 어떻게 알까요? repr(C) 타입과 repr(transparent) 타입들에 대해서는, 어떻게 정렬되는지가 정확하게 정의되어 있습니다. 하지만 당신의 흔해 빠진 repr(Rust) 타입은 그렇지가 않습니다. 같은 제네릭 타입의 다른 인스턴스들조차도 완전히 다르게 정렬될 수 있습니다. Vec<i32>Vec<u32>는 필드들을 같은 순서로 배치했을 수도 있고, 아닐 수도 있습니다. 데이터가 어떻게 배치되는지, 어느 것이 실제로 보장되었는지 혹은 아닌지에 대한 세부 사항은 불안전 코드 가이드라인에서 작업 중입니다.

mem::transmute_copy<T, U>는 이것보다 더하게 엄청나게 불안전한 짓을 어떻게 해 냅니다. 이것은 &T에서 size_of<U>만큼의 바이트를 복사해서 그것을 U라고 해석합니다. mem::transmute가 가지고 있던 크기 검사는 없습니다 (앞부분만 복사하는 것이 올바를 수도 있기 때문입니다), UT보다 크면 미정의 동작이 일어나지만 말이죠.

그리고 당연히 여러분은 이 함수들의 기능을 생 포인터 변형이나 union을 이용해서 전부 사용할 수 있지만, 타입 검사나 다른 기본적인 검사는 제공되지 않습니다. 생 포인터 변형과 union은 위의 규칙들을 마법적으로 피하지는 않습니다.