Both clang and g++ seem compatible with the latest version of the [expr.const] / 5 paragraph in the C ++ standard. The following snippet prints 11 for both compilers. See a 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 do not. Therefore, I must conclude that the code shows undefined behavior, since clang prints an arbitrary number and g++ prints 0 . I would like to know why this is UB, taking into account, for example, draft N4527 standard? Living 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 the answer, which simply says that the code is UB, or shows undefined behavior. I always like to research a little deeper, and sometimes, as now, I was lucky to understand a little more how compilers are composed. And this is what I learned in this case:
Both clang and GCC seem to exclude from the code any unused variable, for example m , for any optimization level greater than -O0 . GCC seems to arrange local variables with static storage durations, similar to how variables are pushed onto 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 as expected.
In GCC , if in addition to this we also change the definition
static int* temp = &n + 1;
to
static int* temp = &n - 1;
we will also get the number 2016 printed in code.