Is const_cast on this pointer undefined behavior?

In another question, I came across this code:

Real StatData::mean(Real trim) const { // trim, pun not intended const_cast<StatData&>(*this).items.sort(); // trim } 

cppreference also has an example on the page:

 struct type { type() :i(3) {} void m1(int v) const { // this->i = v; // compile error: this is a pointer to const const_cast<type*>(this)->i = v; // OK } int i; }; 

Besides the obvious question of why it would ever be practical, it is unsafe? Does it matter if the created object const or not, and more importantly, whether the pointer this safe from undefined The behavior, since it is only marked const for this one function?

+5
source share
2 answers

Does the created object matter or not

Yes. If the object was not created const , then no matter what you do, const_cast will be safe. Just a bad idea (because you don’t know at all which object was not const created).

is this pointer safe from undefined behavior as it is only marked as const for this function?

This is a wrong question, but the fact is that until you try to modify the const object, you are safe. This means that const_cast itself const_cast completely legal and well defined, but if items.sort() changes the material (and we must assume that it does), then this operation leads to UB.

Finally, although you tried to hush up this point in your question, the practicality of this is actually fundamental to the scenario: it is very difficult to guarantee, even in this seemingly concrete case, that the code is safe. Therefore, do not do this. Despite your attempts to abstract it for the purposes of this issue, I cannot stress this.

+9
source

const_cast itself never works undefined. It may be poorly formed, that is, not compiled. But if it is well-formed (i.e. compiled), then it cannot produce undefined behavior by itself.

Undefined behavior can be caused by what you do later, using the [inconsistent] access path obtained with const_cast . But this is a completely different story, not directly related to const_cast .

The code samples you posted so far are not enough to determine if they exhibit undefined behavior or not. It all depends on external factors: on whether the changed object is really declared as const or not. Attempting to change const causes undefined triggers.

For example, for the class type above this code runs the UB

 const type t; t.m1(42); // <- undefined behavior 

while it is not

 type t; t.m1(42); assert(ti == 42); 
+6
source

Source: https://habr.com/ru/post/1200459/


All Articles