Strange behavior of pub constants

Lately, when I read _ it _ I couldn't figure out why the received address and the actual address are different.
when I split the code into modules, it worked.

(playground)

mod module {
    pub const fn give_ptr<T>(x: &T) -> *const T {
        x as *const T
    }
    pub const MY_CONST: &'static i32 = &1;
    pub const fn my_const_ptr() -> *const i32 {
        give_ptr(MY_CONST)
    }
}

fn main() {
    assert_eq!(module::my_const_ptr(), module::give_ptr(module::MY_CONST));
}

according to this article,
this code had to globally save "1" and then clone the reference each time

Instead of creating a new allocation for storing the result of EXPR on every use site, we just have a single global "static" allocation, and every use of REF uses its address. It's as if we had written:


const REF: &u32 = { const _VAL = EXPR; static _STATIC = EXPR; &_STATIC };

Although this article says that

References to the same constant are not necessarily guaranteed to refer to the same memory address.

I just want to understand why when I connect the code to 1 crate it works, and when I divide it,it doesn't,

I assume it's because of Miri, the library reaches us in an already compiled form, and it's easier for him to calculate the data of the called

Constants loosely analogous to #define. References to them can have wildly differing addresses, because the constant is essentially being copy pasted into each of its usage sites.

1 Like

Some of your links are broken.


You can think of the expression of a const being pasted everywhere you use it. So if you have multiple MY_CONST around, it might result in different 1s being put into static memory with different addresses. Or, optimization might combine them and they'll have the same address.

Like Ralf's article says

This is observable when the program compares these pointers for equality. We consider this okay, i.e., programs may not rely on such constants all getting distinct addresses. They may not rely on them all getting the same address either.


It's not reliable either way; it's due to some implementation detail. If I had to guess, it's nothing to do with Miri per se and is because there are multiple compilation units at play when you use multiple crates. But that's just a guess, and the actual reason doesn't matter anyway -- you can't rely on the optimization applying or not; you can't rely on the addresses being the same or distinct. The behavior may change for either case (one crate or multiple) without warning.

If it matters, use static not const.

2 Likes

Sorry, I fixed it

thank you for your answer

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.