This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115b. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-08-20


2878. C-style casts to reference types

Section: 7.6.3  [expr.cast]     Status: open     Submitter: Hubert Tong     Date: 2024-03-20     Liaison: EWG

(From submission #522.)

Consider:

  struct A {};
  struct B : A {};
  const B b;
  void f() {
    (A &&)b;          // #1
    const_cast<A &&>(static_cast<const A &>(b));
    const_cast<A &&>(static_cast<const volatile A &&>(b));
    const_cast<A &&>(static_cast<A>(b));  // slicing interpretation
  }

Is #1 ill-formed because of the three alternative valid interpretations shown in the following lines?

Also consider:

  struct B { };
  const B f();
  B& b1 = const_cast<B&>(static_cast<const B&>(f())); // OK
  B& b2 = (B&)f(); // ???

There is implementation divergence: gcc and MSVC accept, clang and EDG accept b1 and reject b2. If f is changed to return non-const, gcc also rejects b2.

For another example:

  struct A {
    operator const B() = delete;
  } a;

  B& b3 = const_cast<B&>(static_cast<const B&>(a)); // error, deleted
  B& b4 = (B&)a; // error or reinterpret_cast?

Implementations agree that b3 is ill-formed for selecting the deleted conversion operator function, but b4 is considered a reinterpret_cast by the majority of implementations.

CWG 2024-05-17

Casting away rvalueness in example b2 is surprising to perform in a C-style cast. The b4 example is also interesting, because the reinterpret_cast interpretation might be undesirable. EWG is requested to offer guidance, preferably in the form of a comprehensive mental model. The current model "static_cast, then const_cast" might not be appropriate.

See paper issue 1970.