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 keywordthis
is 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 classX
isX*
. 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
T1
andT2
, a prvalue of typeT1
may be explicitly converted to the typeT2
using aconst_cast
. The result of aconst_cast
refers 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