My question is inspired by this answer to another one of my questions: https://stackoverflow.com/a/56989169/2492801.
If I have an actually non-const object, but call one of its const methods, then inside the method this is const of course. If I const_cast away its constness and pass it to another method that performs a write operation on the object pointed to by this, is that undefined behaviour?
I wouldn't be surprised if it was, because this is really const inside a const method. On the other hand, the object itself is non-const so write operations are not generally forbidden.
For me it is important to know that to know how to deal with the problem described in my other question. Thank you!
That's not undefined. That's exactly what const_cast is for. As long as the object itself is non-const then you can cast it away with const_cast and do the same things with it as a non-const pointer.
Do note that const_cast is usually considered a code smell and might indicate bad design.
As the standard says:
In the body of a non-
static([class.mfct]) member function, the keywordthisis a prvalue whose value is a pointer to the object for which the function is called. The type of this in a member function of a classXisX*. If the member function is declared const, the type of this is constX*, if the member function is declaredvolatile, the type of this isvolatile X*, and if the member function is declaredconst volatile, the type of this isconst volatile X*.
The type of this is const X* in your case even though the object itself is non-const.
The standard says this about const_cast:
For two similar types
T1andT2, a prvalue of typeT1may be explicitly converted to the typeT2using aconst_cast. The result of aconst_castrefers to the original entity.
So, casting from const X* to X* is also legal.
Lastly, it says (albeit in a note):
[ Note: Depending on the type of the object, a write operation through the pointer, lvalue or pointer to data member resulting from a const_cast that casts away a
const-qualifier may produce undefined behavior ([dcl.type.cv]). — end note ]
And [dcl.type.cv] tells us:
Any attempt to modify ([expr.ass], [expr.post.incr], [expr.pre.incr]) a const object ([basic.type.qualifier]) during its lifetime ([basic.life]) results in undefined behavior.
Luckily, our this is pointing to a non-const object, so casting it and then modifying this object through the new non-const pointer doesn't trigger undefined behaviour.
Sorry Angew.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With