On 14/04/14 06:12, Vladimir Pouzanov wrote:
I have a number of I/O mapped registers that look like:

struct Dev {
  .. // u32 fields
}

pub static Dev0 : *mut Dev = 0xsomeaddr as *mut Dev;

with macro-generated getters and setters:

pub fn $getter_name(&self) -> u32 {
  unsafe { volatile_load(&(self.$reg)) }
}

unfortunately, calling a getter is calling a method on *Reg, which is unsafe and looks like:

unsafe { (*Dev0).SOME_REG() };

is there any way to simplify the syntax, hopefully to simple Dev0.SOME_REG()? I'm ok with any "unsafe" tricks including transmuting it to &Dev (that doesn't seem to be possible though), as the getter/setter methods are always safe in this scenario.

--
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/


_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev


The compiler cannot verify that these method calls are safe, so they `unsafe`'s are asserting "trust me compiler, I know more than you".


You could write a macro like `get!(Dev0, SOME_REG)` that expanded to the `unsafe { (*Dev0).SOME_REG() }` invocation.


But... I don't understand why transmuting to &Dev wouldn't be possible. I'd strongly recommend the weaker version `unsafe { &*Dev0 }`, to go from *mut Dev to &Dev0. However, this likely breaks the guarantees of &, since the data to which they point is supposed to be immutable, but being I/O mapped registers it would imply that external events can change the values. (I guess this is where Flavio's suggestion of storing a *Unsafe<Dev> comes into play, but this still leaves you dealing with an *mut pointer to get at the data, at the end of the day.)


Huon
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to