简体   繁体   中英

Is const_cast on this pointer undefined behavior?

In another question I ran 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 their 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;
};

Aside from the obvious question of why this would ever be practical, is it unsafe? Does it matter of the object created is const or not and more importantly, is the this pointer safe from undefined behavior because it's only marked const for that one function?

Does it matter of the object created is const or not

Yes. If the object was created non- const , then no matter what you do the const_cast will be safe. Just a bad idea (because in general you don't know what the object was created non- const ).

the this pointer safe from undefined behavior because it's only marked const for that one function?

That's the wrong question really, but the point is that until you try to modify a const object you're safe. That means the const_cast itself is perfectly legal and well-defined, but if items.sort() modifies stuff (and we have to assume it does) then that operation results in UB.

Finally, although you've tried to gloss over this point in your question, the practicality of this is actually fundamental to the scenario: it's remarkably difficult to guarantee, even in this seemingly specific case, that the code is safe. So, don't do it . Despite your attempts at abstracting it away for the purposes of this question, I can't stress that enough.

const_cast itself is never undefined behavior. It could be ill-formed, ie fail to compile. But if it is well-formed (ie compilable) then it cannot produce undefined behavior by itself.

Undefined behavior might be triggered by what you do later with the [non-constant] access path you obtained with the help of const_cast . But it is a completely different story, not directly related to const_cast .

The code samples you posted so far are insufficient to tell whether they exhibit undefined behavior or not. It all depends on the external factors: on whether the object being modified is really declared as const or not. An attempt to modify const object triggers undefined behavior.

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

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

while this one does not

type t;
t.m1(42);
assert(t.i == 42);

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