C-style casts to reference types
7.6.3 [expr.cast]
Hubert Tong

Created on 2024-03-20.00:00:00 last changed 3 weeks ago


Date: 2024-05-24.14:57:23

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.

Date: 2024-03-20.00:00:00

(From submission #522.)


  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.

Date User Action Args
2024-05-24 14:57:23adminsetmessages: + msg7706
2024-03-20 00:00:00admincreate