pub static mut start: [core::ffi::c_char; 0usize];
pub static mut end: [core::ffi::c_char; 0usize];
How Do I get the Address of the variable "start and end"?
pub static mut start: [core::ffi::c_char; 0usize];
pub static mut end: [core::ffi::c_char; 0usize];
How Do I get the Address of the variable "start and end"?
If you’re trying to do the assembly trick where you define three symbols, in order:
start:
Just a labeldata:
Some data, often a stringend:
Just another labeland then do end - start
to calculate the length of data
, that won’t work. Statics in Rust do not have a defined order in the binary.
If your data is a str
or [T]
, the corresponding length functions are const
, so you can define a static LENGTH: usize = DATA.len();
pub static mut start: [core::ffi::c_char; 0usize];
pub static mut end: [core::ffi::c_char; 0usize];
How Do I get the Address of the variable "start and end"?
I suspect that you’re going down a path that doesn’t go anywhere useful, but your question has a straightforward answer:
pub static mut START: [core::ffi::c_char; 0usize] =[];
pub static mut END: [core::ffi::c_char; 0usize] =[];
fn main() {
dbg!(&raw const START);
dbg!(&raw const END);
}
There's also .as_slice().as_ptr()
for arrays in general, but don't use that for static mut
, as the temporary reference has a huge risk of undefined behavior due to breaking Rusts aliasing rules.
That's sort of problem is why static mut
is strongly discouraged now in favor of using plain static
with some interior mutability like at least UnsafeCell
(though you should definitely use something nicer if you can) and why &raw
was added to get a pointer without going through a reference.
There's no point in the static
s being mut
if they're zero length.
This post is definitely an XY problem.
I am not sure what are you going to do.
Using global variable is not a good choice in most case.
Here are code to get address of start.
pub static mut start: [u8; 0usize] = [];
pub static mut end: [u8; 0usize] = [];
fn main() {
unsafe{
let p1 = &start as *const u8;
let p2 = start.as_slice().as_ptr();
println!("address={:p}, {:p}",p1, p2);
}
}
The other posts above tell you how to get the address, but the address won't be predictable like you're expecting.
Also, the compiler may notice that your statics are ZSTs, and therefore not assign them real memory. It could decide that any reference/pointer to them will be 0x01
[1] and that would be a perfectly valid optimization for the compiler[2].
Besides, what do you actually want to do? I talked to you about the XY problem before, and I'll put my response from last time into this context:
start
and end
)Please explain what this is supposed to do. What is your X here? What are the addresses of start
and end
supposed to help you do?
I thought I'd cover this too; a common trick to get this to work again is to assign linker sections explicitly and depend on linker specific behavior. Quite hacky, of course, but you can do some really neat tricks with it.
If you want to measure size of an object file that includes binary data, you don't need to bother with that — Rust has include_bytes!(path)
.
There are two easy way to get its address:
fn main() {
let addr = [0u8; 20];
println!("addr: {:?}", addr.as_ptr());
println!("addr: {:?}", std::ptr::addr_of!(addr));
}