简体   繁体   中英

Is const_cast(this) with a write operation undefined behaviour, if the actual object is non-const?

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 keyword this 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 class X is X* . If the member function is declared const, the type of this is const X* , if the member function is declared volatile , the type of this is volatile X* , and if the member function is declared const volatile , the type of this is const 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 and T2 , a prvalue of type T1 may be explicitly converted to the type T2 using a const_cast . The result of a const_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM