Is the address of a local variable a constexpr?

This answer tries to clarify why the address of a local variable can't be constexpr by analysing an example for the x86-64 architecture.

Consider the following toy function print_addr(), which displays the address of its local variable local_var and call itself recursively n times:

void print_addr(int n) {
   int local_var{};
   std::cout << n << " " << &local_var << '\n';

   if (!n)
      return; // base case

   print_addr(n-1);  // recursive case
}

A call to print_addr(2) produced the following output on my x86-64 system:

2 0x7ffd89e2cd8c
1 0x7ffd89e2cd5c
0 0x7ffd89e2cd2c

As you can see, the corresponding addresses of local_var are different for each call to print_addr(). You can also see that the deeper the function call, the lower the address of the local variable local_var. This is because the stack grows downwards (i.e., from higher to lower addresses) on the x86-64 platform.

For the output above, the call stack would look like the following on the x86-64 platform:

                |     . . .     |
Highest address ----------------- <-- call to print_addr(2) 
                | print_addr(2) |    
                -----------------
                | print_addr(1) |
                -----------------
                | print_addr(0) | <-- base case, end of recursion
Lowest address  ----------------- Top of the stack

Each rectangle above represents the stack frame for each call to print_addr(). The local_var of each call is located in its corresponding stack frame. Since the local_var of each call to print_addr() is located in its own (different) stack frame, the addresses of local_var differ.

To conclude, since the address of a local variable in a function may not be the same for every call to the function (i.e., each call's stack frame may be located in a different position in memory), the address of such a variable can't be determined at compile time, and therefore can't be qualified as constexpr.


An earlier printing of Bjarne Stroustrup's book "The C++ Programming Language (4th Edition)" on p. 267 has the error outlined in the OP's question. The current printing and electronic copies have been "corrected" but introduced another error described later. It now refers to the following code:

constexpr const char* p1="asdf";

This is OK because "asdf" is stored in a fixed memory location. In the earlier printing the book errs here:

void f(char loc) {
    constexpr const char* p0 = &glob; // OK: &glob's is a constant
    constexpr const char* p2 = &loc;  // OK: &loc is constant in its scope
}

However, loc is not in a fixed memory location. it's on the stack and will have varying locations depending on when it is called.

However, the current 4th edition printing has another error. This is the code verbatim from 10.5.4:

int main() {
    constexpr const char* p1 = "asdf";
    constexpr const char* p2 = p1;      // OK
    constexpr const char* p3 = p1+2;    // error:  the compiler does not know the value of p1
}

This is wrong. The compiler/linker does know the value of p1 and can determine the value of p1+2 at link time. It compiles just fine.


It appears that the example from section 10.4.5 provided in my hard-copy of the "The C++ Programming Language (4th Edition)" is incorrect. And so I've concluded that the address of a local variable is not a constexpr.

The example appears to have been updated in some pdf versions as seen here:

enter image description here