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

2023-02-07


2310. Type completeness and derived-to-base pointer conversions

Section: 7.3.12  [conv.ptr]     Status: CD5     Submitter: Richard Smith     Date: 2016-08-08

[Accepted as a DR at the February, 2019 meeting.]

The specification of derived-to-base pointer conversions in 7.3.12 [conv.ptr] paragraph 3 does not require that the derived class be complete at the point of the conversion. This leaves unclear the status of an example like the following, on which there is implementation divergence:

  template<typename A, typename B> struct check_derived_from {
    static A a;
    static constexpr B *p = &a;
  };
  struct W {};
  struct X {};
  struct Y {};
  struct Z : W,
    X, check_derived_from<Z, X>,  // #1 
    check_derived_from<Z, Y>, Y { // #2 
    check_derived_from<Z, W> cdf; // #3 
  };

Notes from the March, 2018 meeting:

The consensus of CWG was that the derived class must be complete at the point of the conversion, and thus all three attempted conversions in the example are ill-formed.

Proposed resolution (November, 2018):

  1. Change 7.3.12 [conv.ptr] paragraph 3 as follows:

  2. A prvalue of type “pointer to cv D”, where D is a complete class type, can be converted to a prvalue of type “pointer to cv B”, where B is a base class (11.7 [class.derived]) of D. If B is an inaccessible...
  3. Change 7.3.13 [conv.mem] paragraph 2 as follows:

  4. A prvalue of type “pointer to member of B of type cv T”, where B is a class type, can be converted to a prvalue of type “pointer to member of D of type cv T”, where D is a complete class derived class (11.7 [class.derived]) of from B. If B is an inaccessible...
  5. Change 7.6.1.9 [expr.static.cast] paragraphs 11 and 12 as followed:

  6. A prvalue of type “pointer to cv1 B”, where B is a complete class type, can be converted to a prvalue of type “pointer to cv2 D”, where D is a class derived (11.7 [class.derived]) from B , if cv2 is the same...

    A prvalue of type “pointer to member of D of type cv1 T” can be converted to a prvalue of type “pointer to member of B of type cv2 T”, where B is a base class (11.7 [class.derived]) of a complete class D, if cv2 is the same...