Я понимаю, что следующий код имеет неопределенное поведение в C++ из-за чего-то, называемого «строгим правилом псевдонимов».Строгое сглаживание в ржавчине?
#include <cstdint>
enum Foo : int16_t {};
void test(Foo& foo) {
reinterpret_cast<int16_t&>(foo) = 42;
}
В частности, компилятор С ++ может опустить назначение вообще, поскольку это позволило предположить, что int16_t&
возвращаемое reinterpret_cast
не указывает на ту же память, как foo
(типа Foo&
), потому что их типы другой.
Вопрос в том, имеет ли Rust что-то похожее на «строгое правило псевдонимов C++»? Другими словами, имеет ли неопределенный код следующий эквивалентный код Rust?
#[repr(i16)]
enum Foo { Dummy }
unsafe fn test(foo: &mut Foo) {
*std::mem::transmute::<&mut Foo, &mut i16>(foo) = 42;
}
EDIT:
Там же несвязанный вопрос с приведенной выше примером Rust кодой в этом test
создает несуществующий вариант перечисления. Итак, вот тот же самый код с быстро исправить:
#[repr(i16)]
enum Foo { Dummy, Yummy = 42 }
unsafe fn test(foo: &mut Foo) {
*std::mem::transmute::<&mut Foo, &mut i16>(foo) = 42;
}
Насколько я понимаю, C/C++, по сути, говорит: «Запись памяти как одного типа и чтение ее как другого типа никогда не бывает хорошо, за исключением случаев, когда вы используете« union »или читаете как« char » , У ржавчины нет такого правила одеяла, и законность зависит от конкретной пары рассматриваемых типов. – glaebhoerl