Search code examples
c++const-cast

address after const_cast of a *const* variable in C++


I know that the following should be undefined behavior since the original variable is const. How is it possible, however, that the two addresses &x and &rx are the same, yet the values which they print (I don't say hold, since it simply cannot be), aren't. Thanks!

const int x=10;
int& rx = const_cast<int&>(x);
rx++;
cout << x << " and " << rx << endl;
cout << "is &x == &xr: " << (&x==&rx) << endl;

the output from G++ 4.9 is

10 and 11
is &x == &xr: 1

Solution

  • The compiler (well, clang++ 3.7.0 as of last week) does indeed optimise the "intention" of the code, regardless of the legality of it:

        movl    $_ZSt4cout, %edi
        movl    $10, %esi
        callq   _ZNSolsEi
        movq    %rax, %rbx
        movl    $.L.str, %esi
        movl    $5, %edx
        movq    %rbx, %rdi
        callq   _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
        movl    $11, %esi
        movq    %rbx, %rdi
        callq   _ZNSolsEi
    

    As always, it's worth noting that the behaviour of undefined behaviour does cover "does what you think it will do", as well as "doesn't do what you think it will do", and this CERTAINLY applies here.

    const_cast of a value that was originally const is undefined behaviour, and at that point you have given up all rights to "sane behaviour" from the compiler. What happens now is whatever the compiler writer thinks is the right thing - and if that means the value actually got placed in a read-only bit of memory, then your code will not succeed in updating the value. But in this case, it simply optimises x to the constant 10, and rx becomes 11 - since you don't actually "do" anything else with x and rx, that's "fine" by the compilers standards.