0

Is it possible to modify a const field of a non-const object (using const_cast) in C++20?

Yes, I know it probably shouldn't be allowed, and that there are very similar questions (Move construction and assignment of class with constant member, Replace a variable of a type with const members). But some answers and comments seem to suggest that it's possible in C++20; but I can't find anything that clearly says it's allowed.

For example:

As of c++20 you can modify a const member object. There's even a constexpr function to do so, construct_at and well as destroy_at in case the the object has a non-trivial dtor. – doug Apr 14

(comment to https://stackoverflow.com/a/68018681/8245776)

As well as this answer (https://stackoverflow.com/a/71805401/8245776), which I honestly don't really understand, but it seems to be saying that it is possible in C++20.

So is it possible to do this in C++20, or am I misunderstanding those answers?

Edit:

Ok so, judging from the mentioned questions, I think the answer is that it's possible in C++20? I'm still not sure though, so if anyone could confirm this, that would be appreciated.

Joel Niemelä
  • 168
  • 1
  • 3
  • 13
  • 1
    Strictly `construct_at` doesn't *modify* an object, it creates a new one. – BoP Jul 03 '22 at 07:52
  • If you have access pretty sure you can just remove the const off whatever with auto* notConst = const_cast(&member); Some things may break/work differently than expected if you do this, as the compiler optimizes with this value. – Natio2 Jul 03 '22 at 10:07
  • @BoP right, but is it legal to access that new object through the old (const) variable? Or does that result in undefined behavior? Judging from what others have said, it seems like it *is* legal, but since const_cast isn't and (at least effectively) does the "same thing" (I know it's different under the hood), it feels like `construct_at` should also be illegal. – Joel Niemelä Jul 03 '22 at 22:30
  • 1
    `construct_at` returns a pointer to the new object. That pointer would be valid. Using an old pointer could be a problem, as the compiler can (quite reasonably) assume that a const object doesn't change. You could (perhaps) use [std::launder](https://en.cppreference.com/w/cpp/utility/launder) to wash that away, but I'm not sure exactly how that works. – BoP Jul 04 '22 at 08:47
  • @ BoP Ah I see. So, as long as I can guarantee I don't have old pointers to it, it should be ok. And also, I'm assuming I can access the new object through the member variable (It's not a pointer, just a plain value member) without laundering it? Thank you for all your help. – Joel Niemelä Jul 04 '22 at 13:20
  • 1
    @BoP `std::launder` was required to access this modified const data prior to c++20. As of c++20, the modified const becomes immediately alive and one can refer to member variables in the normal way. See [basic.lifetime](https://timsong-cpp.github.io/cppwp/n4868/basic.life#8) – doug Jul 05 '22 at 19:21

0 Answers0