Proposed resolution (approved by CWG 2024-03-20): Change in 7.6.3 [expr.cast] paragraph 4 as follows:
... If a conversion can be interpreted in more than one of the ways listed
above, the interpretation that appears first in the list is used, even
if a cast resulting from that interpretation is ill-formed. If a
conversion can be interpreted in more than one way as
a static_cast followed by a const_cast is
used and the conversion can be interpreted in more than one way as
such, the conversion is ill-formed.
[ Example 1 :
struct A { };
struct I1 : A { };
struct I2 : A { };
struct D : I1, I2 { };
A* foo( D* p ) {
return (A*)( p ); // ill-formed static_cast interpretation
}
int*** ptr = 0;
auto t = (int const*const*const*)ptr; // OK, const_cast interpretation
struct S {
operator const int*();
operator volatile int*();
};
int *p = (int*)S(); // error: two possible interpretations using static_cast followed by const_cast
-- end example ]
[Accepted as a DR at the March, 2024 meeting.] (From editorial issue
5355.) Consider: There is more than one way how this can be interpreted as
a static_cast followed by a const_cast , namely: Subclause 7.6.3 [expr.cast] paragraph 4 makes such a program ill-formed:
int*** ptr = 0;
auto t = (int const*const*const*)ptr;
const_cast<int const * const * const * >(static_cast<int * * const * >(ptr));
const_cast<int const * const * const * >(static_cast<int * const * const * >(ptr));
... If a conversion can be interpreted in more than one way as a
static_cast followed by a const_cast , the conversion
is ill-formed.