Description
References to constants are not guaranteed to have unique addresses:
assert!(&2 as *const i32 != &2 as *const i32); // fails
Since const
s are just aliases, the same holds for those:
const A: i32 = 2;
const B: i32 = 2;
assert!(&A as *const i32 != &B as *const i32); // fails
What about static
s? static
variables with interior mutability (and static mut
variables) obviously must have unique addresses, but what about ones without?
static A: i32 = 2;
static B: i32 = 2;
assert!(&A as *const i32 != &B as *const i32); // passes
And local variables? (Assuming that both variables are alive at the point of comparison, since obviously variables that have fallen out of scope can have their addresses reused.)
let a = 2;
let b = 2;
assert!(&a as *const i32 != &b as *const i32); // passes
Currently, rustc seems to produce unique addresses in both cases. But @gnzlbg is under the impression that multiple local variables are not guaranteed to have distinct addresses.
Address uniqueness can be a useful property, e.g. if you want a unique 'sentinel' value to assign to a pointer variable. On the other hand, I'd say Rust usually avoids giving much significance to something being a variable as opposed to an expression.
A related issue is #15, which is about whether the address of something can change over time.
Compared to C and C++
In C, rvalues are not implicitly bound to addresses unless assigned to a variable (or a C99 compound literal). C appears to guarantee that distinct variables have distinct addresses.
In C++, rvalues can be implicitly bound to const references, which gives them an address: this is "temporary materialization" and creates a "temporary object". Like C, the C++ spec guarantees that distinct "objects" "compare unequal", so I think this assertion is guaranteed to pass (not sure though):
#include <assert.h>
void foo(const int &a, const int &b) {
assert(&a != &b);
}
int main() {
foo(2, 2);
}
In practice, this means that the compiler always stores a copy of the constant on the stack and takes the address of that, rather than directly referencing a static allocation.