Is private really private?

Here is one way you can escape rust's privacy rules (surely there are others as well):

mod M {
    pub struct MyStruct {
        priv_field: u32,
    }

    impl MyStruct {
        pub fn new() -> MyStruct {
            MyStruct { priv_field: 42 }
        }
    }
}

struct MyStructHax {
    pub priv_field: u32
}

fn main() {
    let s = M::MyStruct::new();

    // this will not compile:
    //let x: u32 = s.priv_field;
    
    let s_exposed: MyStructHax = unsafe { std::mem::transmute(s) };
    let x = s_exposed.priv_field;
}

First a new struct was defined that has the same layout at the one you wish to expose, but with a public field. Then you use std::mem::transmute to convert to the new struct. Now the field is accessible.

This is not hard to do, but as I mentioned above, you have to be very deliberate about this -- you need to look up the struct definition you want to expose and use an unsafe transmute. You would never do this on accident. This is what I mean by having to do "work" to expose a private field.

C++ will happily let a programmer shoot themselves in their own foot, especially when the programmer doesn't mean to. Rust also will let a programmer shoot themselves in the root, but doing this by accident or unintentionally is very hard.

3 Likes