Both clang and g++ seem to be compliant with the last version of the paragraph [expr.const]/5 in the C++ Standard. The following snippet prints 11 for both compilers. See live example:
#include <iostream>
void f(void) {
static int n = 11;
static int* temp = &n;
static constexpr int *&&r = std::move(temp);
std::cout << *r << '\n';
}
int main()
{
f();
}
According to my understanding of this paragraph both compilers should print 2016 for the code below. But they don't. Therefore, I must conclude that the code shows undefined behavior, as clang prints an arbitrary number and g++ prints 0. I'd like to know why is it UB, taking into consideration, for example, the draft N4527 of the Standard? Live example.
#include <iostream>
void f(void) {
static int n = 11;
static int m = 2016;
static int* temp = &n + 1;
static constexpr int *&&r = std::move(temp);
std::cout << *r << '\n';
}
int main()
{
f();
}
Edit
I have a habit of not being satisfied with an answer that just says the code is UB, or shows undefined behavior. I always like to investigate a little deeper, and sometimes, as now, I happen to be lucky enough to understand a little bit more, how compilers are built. And that's what I found out in this case:
Both clang and GCC seem to eliminate any unused variable, like m, from the code, for any optimization level greater than -O0. GCC seems to order local variables with static storage duration, the same way variables are placed on the stack, i.e., from higher to lower addresses.
Thus, in clang, if we change the optimization level to -O0 we get the number 2016 printed as expected.
In GCC, if in addition to that, we also change the definition of
static int* temp = &n + 1;
to
static int* temp = &n - 1;
we will also get the number 2016 printed by the code.