Rust lang:为什么在引用后面创建的临时/局部变量在作用域结束后不被删除?



有人能帮我解释一下下面的代码吗?在作用域1和2中,创建的局部变量在它们的作用域结束时被删除,这是预期的。然而,在作用域3和4中,在引用后面声明的局部变量似乎没有被删除,作用域4中声明的局部变量就在作用域3中声明的局部变量旁边,而不是替换它。然后,在作用域5中,在引用后面声明了一个局部变量,但具有与作用域3相同的值,但不是在作用域4中声明的局部变量的地址上移1字节,而是给出了作用域3中声明的局部变量的地址。在思考了rust为什么会这样做之后,我最好的猜测是这是rust编译器的工作,它这样做是为了优化代码。

pub fn scope_1() -> *const u8 {
let ui: u8 = 1;
return &ui as *const u8;
}
pub fn scope_2() -> *const u8 {
let ui: u8 = 2;
return &ui as *const u8;
}
pub fn scope_3() -> *const u8 {
let uip: &u8 = &3;
return uip as *const u8;
}
pub fn scope_4() -> *const u8 {
let uip: &u8 = &4;
return uip as *const u8;
}
pub fn scope_5() -> *const u8 {
let uip: &u8 = &3;
return uip as *const u8;
}
fn main() {
unsafe {
let s1 = scope_1();
print!("scope 1 ptr: {:?}n", s1); // 0x56da2ff3f7
print!("scope 1 val: {}n", *s1);  // 0
let s2 = scope_2();
print!("scope 2 ptr: {:?}n", s2); // 0x56da2ff3f7
print!("scope 2 val: {}n", *s2);  // 0
let s3 = scope_3();
print!("scope 3 ptr: {:?}n", s3); // 0x7ff64676e458
print!("scope 3 val: {}n", *s3);  // 3
let s4 = scope_4();
print!("scope 4 ptr: {:?}n", s4); // 0x7ff64676e459
print!("scope 4 val: {}n", *s4);  // 4
let s5 = scope_5();
print!("scope 5 ptr: {:?}n", s5); // 0x7ff64676e458
print!("scope 5 val: {}n", *s5);  // 3
}    
}

首先,*s1*s2是UB,所以从这一点得出的任何观察都是绝对无意义的,没有一个是可靠的,因为就编译器而言,它不会发生。

第二,你观察到的范围3到5(不确定为什么你需要3个)是持续的推广。

也就是说,因为你引用的是琐碎的字面量

可以写在常量中并借用

而不是分配堆栈槽和借用,编译器将常量提升为static,存储在二进制中,然后创建&'static借用。

最新更新