Skip to content

When are things guaranteed to have unique addresses? #206

Open
@comex

Description

@comex

References to constants are not guaranteed to have unique addresses:

assert!(&2 as *const i32 != &2 as *const i32); // fails

Since consts 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 statics? 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-pointer-equalityTopic: Related to questions of pointer equality/identityC-open-questionCategory: An open question that we should revisitS-pending-designStatus: Resolving this issue requires addressing some open design questions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions