简体   繁体   中英

Does dereferencing a pointer from a const_cast ALWAYS invoke undefined behavior?

See the following:

struct A
{
    std::string* get() const
    {
        //return const_cast<std::string*>(&m_pObj);
        return &const_cast<A*>(this)->m_pObj;
    }

    std::string m_pObj;
};

Is dereferencing const_cast of this UB? Is there any time dereferencing the result from const_cast ing the constness of a pointer away doesn't invoke UB?

(I know the above example is bad practice, bad design, and could be solved with mutable - that's not the point)

Is dereferencing const_cast of this UB? Is there any time dereferencing the result from const_casting the constness of a pointer away doesn't invoke UB?

Not always, only if the object is const (the A instance is const A x; ) and the dereference is used to modify the data. If it is only used to read it will not be undefined behavior, if the object is not const, (maybe not at all, maybe a const-reference to a non-const object) it won't be UB either.

No, it is only UB if the referenced object has been declared as const originally and you subsequently modify the data obtained by the cast (§5.2.11/7 and §7.1.6.1/4). The following is legal:

A a;
a.get()->clear();

while this isn't (and is consequently UB):

A const a;
a.get()->clear();

No. To wit:

5.2.2 Function call

5 [ Note: a function can change the values of its non-const parameters, but these changes cannot affect the values of the arguments except where a parameter is of a reference type (8.3.2); if the reference is to a const-qualified type, const_cast is required to be used to cast away the constness in order to modify the argument's value. Where a parameter is of const reference type a temporary object is introduced if needed (7.1.6, 2.14, 2.14.5, 8.3.4, 12.2). In addition, it is possible to modify the values of nonconstant objects through pointer parameters. —end note ]

However,

5.2.11 Const cast

12 [ Note: some conversions which involve only changes in cv-qualification cannot be done using const_cast. For instance, conversions between pointers to functions are not covered because such conversions lead to values whose use causes undefined behavior. For the same reasons, conversions between pointers to member functions, and in particular, the conversion from a pointer to a const member function to a pointer to a non-const member function, are not covered. —end note ]

A compiler is free to store a const value in read-only memory, it is free to make assumptions that it will never change when optimising the program. If you cast away the constness, you are breaking the contract with the compiler so technically anything can happen.

Realistically, it is pretty rare for a compiler to do something that will be broken by const_cast-ing, but in theory it is possible.

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