Search code examples
crustborrow-checkerstack-memorystack-pointer

What is the RUST equivalent of following C code?


I have a small C code which demonstrate Runtime Stack functionality by modifying data at a stack address.

#include <stdio.h>

int * fun() {
    int a = 10;
    return &a;
}
int * fun2() {
    int b = 20;
    return &b;
}

int main () {
    int *a = fun();
    int *b = fun2();
    printf("a:%d b:%d\n", *a, *b);
    return 0;
}

Output of this is : a:20 b:20 which shows 'b' in 'fun2' used the same stack address as 'a' in 'fun'.

i want to test this in Rust too. What would be the simplest way to do this?

I tried Borrowing but compiler says "No value to borrow".


Solution

  • If you want to have the same undefined behavior as in C, you can do (luckily, this requires unsafe):

    fn fun() -> *const i32 {
        let a = 10;
        &a
    }
    
    fn fun2() -> *const i32 {
        let b = 20;
        &b
    }
    
    fn main() {
        let a = fun();
        let b = fun2();
        // SAFETY: Don't do this. This is pure Undefined Behavior.
        unsafe {
            println!("a: {} b: {}", *a, *b);
        }
    }
    

    And this is UB exactly as with the C version. It prints a: 21885 b: 21885 on the playground on debug mode, and a: -482758656 b: 32767 on release mode. Yours will be different.

    If you also want the same result as the C version, you can use printf(). Be careful with the code you use, changes can cause it to no longer "work" as it will use a different stack layout. Of course, this is very fragile:

    use std::ffi::c_char;
    
    fn fun() -> *const i32 {
        let a = 10;
        &a
    }
    
    fn fun2() -> *const i32 {
        let a = 20;
        &a
    }
    
    extern "C" {
        fn printf(format: *const c_char, ...);
    }
    
    fn main() {
        let a = fun();
        let b = fun2();
        unsafe {
            printf(b"a: %d b: %d\n\0" as *const u8 as *const c_char, *a, *b);
        }
    }
    

    It prints a: 20 b: 20 on debug mode, and a: 1 b: 1 on release (and yours may be different).