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.
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.
const_cast only change the type, but doesn't change the binary representation of this pointer. So the behavior changes only if the called member function is const-overridden. So the answer to your question is NO.
So the point of const_cast away is to allow this type of manipulation, and you are expected to know if it is safe or not, as a programmer.
Where it could go wrong is if you have an aggregate object with "acceptable" member methods. No constructors, destructors, virtuals, mutable members, members that are themselves non-aggregates, nor may it be derived.
An instance of such an object could be declared in static space as constant, and the compiler might instance that object into a predefined immutable memory block. Performing a const_cast away on that object and trying to modify it, either with a global function or from your member function, will cause "undefined behaviour", probably an exception, possibly an uncatchable fault, almost certainly leading to program termination.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.