For FFI, can I depend on const &'static addresses?

Hello Rust forum!

I'm unsure as to when I can depend on a &'static reference to a const to be stable enough to send over an FFI boundary.

Originally I thought all consts were inlined but it seems more nuanced than that. Can I depend on const going through static memory promotion to send a pointer to it over an FFI boundary? My thinking is that if a const is inlined (therefore on the stack), then I can't depend on that address.

Here's an example of what I was trying to work with to get a better understanding:

struct TestInner {
    val: usize
}

struct ConstTest;

impl ConstTest {
    const TEST_INNER: TestInner = TestInner {
        val: 12
    };
    
    pub fn get() -> &'static TestInner {
        &Self::TEST_INNER
    }
}

fn main() {
    let test_1 = ConstTest::get();
    let test_2 = ConstTest::get();
    println!("{:p}", test_1 as *const TestInner);
    println!("{:p}", test_2 as *const TestInner);
}

Can I send test_1 as *const TestInner over to C code? The C code assumes the pointer will be valid past the current stack frame (and in my head this is valid since it lives in static memory).

Thank you!

If you have a &'static T to anything, then it's fine to send over FFI, no matter how you got it. It will definitely be valid forever.

3 Likes

If you get a static reference out of a const, you can be sure it's been promoted. However, due to the inlining-like quality you mention, you may get more than one distinct &'static address from a single const definition. If this is a problem, you'll need a static to reference.

2 Likes

Ooo, okay. So in that example I posted, I could theoretically get 2 different addresses in the println! statements but I can confident that both will be valid forever? A static item, though, guarantees me the same address.

Right. Even if you have a const SR: &'static i32 = &32, the entire expression is inlined, so the literal on the right may get promoted in different places. If so, though, they'll all be valid forever.

See: constant reference has unstable address acrosss compilation units. · Issue #72004 · rust-lang/rust · GitHub

1 Like

I really hate it when people say "well actually...", but there are obscure situations where the guarantees Rust makes around &'static T references are broken.

One that comes to mind is where the OS unloads part of your address space. For example, if you load a library at runtime with something like dlopen(), all &'static str string literals passed to the main application by the library will become invalid when the library is closed.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.