3

Playing around with constexpr and realised I was able to cast away the constness in much the same way as a regular const object:

#include <iostream>

int main() 
{
    // your code goes here
    constexpr int foo = 10;
    int* bad = const_cast<int*>(&foo);
    *bad = 5;
    std::cout<<*bad<<'\n';
    return 0;
}

Will print 5, and I was surprised that this even compiled? However when making the variable static I was even more confused:

#include <iostream>

int main() 
{
    // your code goes here
    static constexpr int foo = 10;
    int* bad = const_cast<int*>(&foo);
    *bad = 5;
    std::cout<<*bad<<'\n';
    return 0;
}

This prints 10, meaning that the assignment operator silently failed, again no warnings at compile time.

Is there a section in the standard that explains the behaviour of const_cast on constexpr objects?

nitronoid
  • 1,459
  • 11
  • 26
  • 1
    The standard's opinion on this boils down to "`const_cast`ing away constness from things that are _actually_ `const` and then doing non-const things with them is undefined behavior". This allows compilers to do clever things (which may end up causing mayhem if you violate the rules). – Max Langhof Jul 10 '18 at 16:41
  • 1
    @MaxLanghof I suppose I'm more confused about the fact that this was permitted on a `constexpr` object rather than just a `const` one. Perhaps my understanding of the difference between the two is incorrect? – nitronoid Jul 10 '18 at 16:44
  • Undefined behavior is undefined. – Barry Jul 10 '18 at 16:51
  • [`constexpr` also implies `const`](https://timsong-cpp.github.io/cppwp/n4659/dcl.dcl#dcl.constexpr-9), and that's all it does in terms of constness. `const_cast` allows you (for example) to pass a `const` value to a function that expects a non-const reference, which is completely fine _as long as the function does not actually modify the value_. So using `const_cast` on a `constexpr` has no reason to be forbidden. Modifying the resulting non-const object is forbidden though, and compilers are not required to trace this for you. – Max Langhof Jul 10 '18 at 17:01
  • `constexpr int foo = 10;` and `const int foo = 10;` have exactly the same semantics. The `constexpr` keyword just validates that the initializer was a constant expression, it does not impose any constraints on future use of the object – M.M Jul 11 '18 at 00:38

0 Answers0