Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Rust lang: Why is the temporary/local variable created behind a reference not dropped after the scope ends?

Can someone help me explaining the following code? In scope 1 and 2, the local variable created get dropped when their scope ends which is as expected. However in scope 3 and 4, it seems that the local variable declared behind a reference did not get dropped, the local variable declared in scope 4 is right next to that in scope 3 instead of replacing it. Then again, in scope 5 a local variable is declared behind a reference but with the same value as that of scope 3, but instead of going 1 byte up in address of local variable declared in scope 4, it was given the address of the local variable declared in scope 3. After many thoughts on why rust is behaving this way, my best guess is that this is the work of rust compiler and it does this to optimize the code.

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
    }    
}

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

First of all, *s1 and *s2 are UB so any observation made from this is categorical nonsense, none of it is reliable because as far as the compiler is concerned it doesn’t happen.

Second, what you’re observing with scope 3 to 5 (not sure why you needed 3 of them) is constant promotion.

That is, because you’re referencing trivial literals which

could be written in a constant and borrowed

rather than allocate a stack slot and borrow that the compiler promotes the constant to a static, stores that in the binary, and then creates an &'static borrow.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading