Skip to content

CWG2879 [expr.const.cast] Clean up specification of const_cast #526

Closed
cplusplus/draft
#7458
@t3nsor

Description

@t3nsor

Full name of submitter: Brian Bi

Reference (section label): [expr.const.cast]

Issue description: There are a few issues here.

The current specification allows constructs like const_cast<int>(0) and const_casts involving function pointers and pointers to member functions, but this is probably unintentional, and no implementations accept them. We need to say that a cast to object type is allowed only if the object type is an object pointer or pointer to data member type.

"The result of a const_cast refers to the original entity" in paragraph 3 is wrong; it should say "points". Also, the sentence about null pointers is 2 paragraphs down, which is odd.

CWG891, adopted for C++11, made const_cast<int&&>(2) illegal. However, [expr]/7 now says:

Whenever a prvalue appears as an operand of an operator that expects a glvalue for that operand, the temporary materialization conversion is applied to convert the expression to an xvalue.

and [expr.const.cast]/4.2 says:

a glvalue of type T1 can be explicitly converted to an xvalue of type T2 using the cast const_cast<T2&&> [...]

Taken together, this implies that const_cast<int&&> expects a glvalue operand, so a prvalue can be materialized to produce the expected glvalue, which contradicts the intent.

Also, the resolution of CWG891 for some reason treats class prvalues and array prvalues unequally. We may want to fix this. The suggested resolution below leaves the current behavior alone, but it would be easy to amend it if we want a change in this area.

Suggested resolution:

Strike the last two sentences from [expr.const]/1:

The result of the expression const_cast(v) is of type T. If T is an lvalue reference to object type, the result is an lvalue; if T is an rvalue reference to object type, the result is an xvalue; otherwise, the result is a prvalue and the lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard conversions are performed on the expression v. Conversions that can be performed explicitly using const_cast are listed below. No other conversion shall be performed explicitly using const_cast.

Replace the text in [expr.const]/3 with the following, leaving the examples:

If T is an object pointer type or pointer to data member type, the type of v shall be similar to T and the corresponding P_i components of the qualification decompositions of T and the type of v shall be the same ([conv.qual]). If v is a null pointer or null member pointer, the result is a null pointer or null member pointer, respectively. Otherwise, the result points to or past the end of the same object or member, respectively, as v.

Replace [expr.const]/4 with:

Otherwise, T shall be a reference type. Let T1 be the type of v and T2 be the type referred to by T. A const_cast from "pointer to T1" to "pointer to T2" shall be valid. If T is an lvalue reference type, v shall be an lvalue. Otherwise, if T2 is a class type and v is a prvalue, the temporary materialization conversion ([conv.rval]) is applied. Otherwise, the temporary materialization conversion is not applied and v shall be a glvalue. The result refers to the same object as the (possibly converted) operand.

Strike [expr.const]/5:

A null pointer value ([basic.compound]) is converted to the null pointer value of the destination type.
The null member pointer value ([conv.mem]) is converted to the null member pointer value of the destination type.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions