c++cross-platformstack-memoryaddressofpass-by-const-reference

When is the address of a const reference function parameter unique?


In my example code below, I'd like to know when two calls to log_cref_address will reliably print the same address.

#include <iostream>
#include <thread>
#include <functional>

using namespace std;

void log_cref_address(const int& t) {
    cout << addressof(t) << ' ';
}

template <int i>
void foo() {
    log_cref_address(i); // different if foo called from different threads
    thread([] { log_cref_address(i); }).join(); // same if already in thread
    thread(log_cref_address, i).join(); // same if already in thread
    cout << endl;
}

int main() {
    // first three calls print identical addresses
    cout << "foo<0>: "; foo<0>(); 
    cout << "foo<0>: "; foo<0>();
    cout << "foo<1>: "; foo<1>();
    cout << endl;
    // last two from thread yields different addresses from the first three
    cout << "lambda: "; thread([] { foo<0>(); }).join();
    cout << "bind(): "; thread(bind(foo<0>)).join();
    return 0;
}

On my machine, main prints

foo<0>: 0x7fff7cf5507c 0x7fa0585b5e1c 0x196fc28 
foo<0>: 0x7fff7cf5507c 0x7fa0585b5e1c 0x196fc28 
foo<1>: 0x7fff7cf5507c 0x7fa0585b5e1c 0x196fc28 

lambda: 0x7fa0585b5dcc 0x7fa057db4e1c 0x7fa0500008c8 
bind(): 0x7fa0585b5d1c 0x7fa057db4e1c 0x7fa0500008c8

From many outputs like this, I've observed that main behaves as follows:

  1. The first three calls to foo print identical addresses.
  2. The last two calls to foo (from threads) print addresses not printed by the first three calls.
  3. In the last two calls to foo, log_cref_address prints the same address if and only if called from a sub-thread.

Which (if any) of these behaviors are guaranteed by the C++ standard, on any machine?


Solution

  • None of them. The standard doesn't guarantee the address of a temporary variable.