Search code examples
c++constantslanguage-lawyerundefined-behaviortemporary-objects

Is temporary object originally const?


Is this code UB?

struct A
{
 void nonconst() {}
};

const A& a = A{};
const_cast<A&>(a).nonconst();

In other words, is the (temporary) object originally const? I've looked through the standard but cannot find an answer so would appreciate quotations to relevant sections.

Edit: for those saying A{} is not const, then can you do A{}.nonconst() ?


Solution

  • The initialization of the reference a is given by [dcl.init.ref]/5 (bold mine):

    Otherwise, if the initializer expression

    • is an rvalue (but not a bit-field)[...]

    then the value of the initializer expression in the first case and the result of the conversion in the second case is called the converted initializer. If the converted initializer is a prvalue, its type T4 is adjusted to type “cv1 T4” ([conv.qual]) and the temporary materialization conversion ([conv.rval]) is applied.

    So it means that the type prvalue expression that initialize the reference, A{}, is adjusted to const A.

    Then [conv.rval] states:

    A prvalue of type T can be converted to an xvalue of type T. This conversion initializes a temporary object ([class.temporary]) of type T.

    So the type of the temporary object, bound to the reference is the same as the adjusted prvalue type: const A.

    So the code const_cast<A&>(a).nonconst(); is undefined behavior.