Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What assumptions can C++ compilers make about pointers that compare equal?

I am interested in what assumptions C++ compilers can make about pointers that do compare equal. Specifically, in the following situations:

  1. The same physical page is mapped at multiple virtual addresses.
  2. Different "threads" of execution working on what is, morally, the same program might have the same virtual address mapped to different physical pages.

Same Physical Page and Multiple Virtual Addresses

In the first case (the same page mapped at multiple addresses), consider the following program.

int test(int* p, int* q) {
  if (p != q) {
    auto t = *q;
    *p = 1;
    return t;
  } else {
    *p = 1;
    return *q;
  }
}

Since p and q are both pointers to the same (non-volatile) type that do not compare equal, it might be possible for C++ to assume that the write to p can be lifted out of the conditional and the program optimized to:

int test(int* p, int* q) {
  *p = 1;
  return *q;
}

However, if p and q are pointers to different virtual addresses that are backed by the same physical page, this optimization is no longer legal. Is there anything in C++ that would make this sort of setup program UB?

Same Virtual Address Maps to Different Physical Pages for Different "threads"

In some OS contexts, different cores run the same binary code with a shared heap but have slightly different page tables for some addresses. For example, the address 0x8000 might be mapped to a different page on each core so that each core can access its thread local state without needing to use a register. In this case, these pointers should clearly not be shared between different cores, e.g. by putting them on the heap, but does C++ say anything about this? The two pointers will compare equal (if they were compared), but they refer to different objects (which seems to be forbidden by the standard).

like image 410
Gregory Avatar asked Nov 01 '25 14:11

Gregory


1 Answers

An implementation with that sort of page tables is simply not a conforming implementation of C++. Technically the same is true of the mmap case, since that isn’t an identifier reserved to the implementation and it can’t be implemented as a (C++) library.

Of course, the way we usually think about this is that implementation-provided functions can cause semantics that are otherwise impossible; here we would say that it causes it to be undefined behavior to use these distinct, aliasing pointers (because that’s the only reasonable way to explain the optimizations that compilers do in fact perform). In practice, people who need these features battle that undefined behavior with tricks like using volatile (as you already hinted at).

like image 162
Davis Herring Avatar answered Nov 03 '25 04:11

Davis Herring



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!