La mia comprensione è che il codice seguente ha un comportamento non definito in C++ a causa di qualcosa chiamato "regola di aliasing rigoroso".Aliasing rigoroso in Rust?
#include <cstdint>
enum Foo : int16_t {};
void test(Foo& foo) {
reinterpret_cast<int16_t&>(foo) = 42;
}
In particolare, un compilatore C++ può omettere l'assegnazione complessivamente perché è permesso assumere che la int16_t&
restituito dal reinterpret_cast
non punta alla stessa memoria, come foo
(di tipo Foo&
) perché i loro tipi sono diverso.
La mia domanda è, Rust ha qualcosa di simile alla "rigida regola di aliasing" del C++? In altre parole, il seguente codice Rust equivalente ha un comportamento indefinito?
#[repr(i16)]
enum Foo { Dummy }
unsafe fn test(foo: &mut Foo) {
*std::mem::transmute::<&mut Foo, &mut i16>(foo) = 42;
}
EDIT:
C'è un problema non correlato con il codice di esempio Rust sopra che test
crea una variante enum non esistente. Quindi, ecco lo stesso codice con una soluzione rapida:
#[repr(i16)]
enum Foo { Dummy, Yummy = 42 }
unsafe fn test(foo: &mut Foo) {
*std::mem::transmute::<&mut Foo, &mut i16>(foo) = 42;
}
Per quanto ne so: C/C++ dice essenzialmente "scrivere memoria come un tipo e leggerlo come un tipo diverso non va mai bene, tranne se si sta usando un 'union', o si legge come' char' " . La ruggine non ha una tale regola generale e la legalità dipende dalla particolare coppia di tipi in questione. – glaebhoerl