简体   繁体   中英

Why can I modify const_cast-ed object in constexpr function?

I always assumed:

  • writing to const_cast ed variable is UB
  • there is no UB allowed in constexpr

So I am confused why this code compiles :

constexpr int fn(){
    int v = 42;
    return [v]() {
        const_cast<int&>(v)+=5;
        return v;
    }();
}
static constexpr auto val = fn();
int main() {
    return val;
}

note: I know there is no reason to not allow this to work since it is obvious what the result should be, I am more interested in the legal explanation why is this allowed.

This part is true:

there is no UB allowed in constexpr

This part is not:

writing to const_cast -ed variable is UB

The actual rule is, from [dcl.type.cv]/4 :

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.

Note that the relevant part is whether the object is const or not - not whether any of the path that you took to get to it is const . And in this case, v is not a const object and nor is the one created in the lambda when you're copying it.

However, if you declare v to be const , then the one declared in the lambda would also be declared const , and thus the attempt to modify it would be undefined behavior. As a result, your code will no longer compile.

The lambda expression translates to something similar to this:

struct unnamed {
    int v;
    int operator()() const {
       const_cast<int&>(v)+=5;
       return v;
    }
};

Without the const_cast you cannot modify v inside the operator() because the operator is a const method, but v itself is not const .

Same situation as with

struct foo {
    int x = 0;
    void operator() const {
        const_cast<int&>(x) += 42;
    }
};

Then this is "ok":

foo f;
f();

While this is undefined:

const foo f;
f();

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