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

2024-03-20


520. Old-style casts between incomplete class types

Section: 7.6.3  [expr.cast]     Status: CD1     Submitter: comp.std.c++     Date: 19 May 2005

[Voted into WP at April, 2007 meeting.]

7.6.3 [expr.cast] paragraph 6 says,

The operand of a cast using the cast notation can be an rvalue of type “pointer to incomplete class type”. The destination type of a cast using the cast notation can be “pointer to incomplete class type”. In such cases, even if there is a inheritance relationship between the source and destination classes, whether the static_cast or reinterpret_cast interpretation is used is unspecified.

The wording seems to allow the following:

  1. casting from void pointer to incomplete type

  2.     struct A;
        struct B;
    
        void *v;
        A *a = (A*)v; // allowed to choose reinterpret_cast
    
  3. variant application of static or reinterpret casting

  4.     B *b = (B*)a;    // compiler can choose static_cast here
        A *aa = (A*)b;   // compiler can choose reinterpret_cast here
        assert(aa == a); // might not hold
    
  5. ability to somehow choose static_cast

  6. It's not entirely clear how a compiler can choose static_cast as 7.6.3 [expr.cast] paragraph 6 seems to allow. I believe the intent of 7.6.3 [expr.cast] paragraph 6 is to force the use of reinterpret_cast when either are incomplete class types and static_cast iff the compiler knows both types and there is a non-ambiguous hierarchy-traversal between that cast (or maybe not, core issue 242 talks about this). I cannot see any other interpretation because it isn't intuitive, every compiler I've tried agrees with me, and neither standard pointer conversions (7.3.12 [conv.ptr] paragraph 3) nor static_cast (7.6.1.9 [expr.static.cast] paragraph 5) talk about incomplete class types. If the committee agrees with me, I would like to see 7.3.12 [conv.ptr] paragraph 3 and 7.6.1.9 [expr.static.cast] paragraph 5 explicitly disallow incomplete class types and the wording of 7.6.3 [expr.cast] paragraph 6 changed to not allow any other interpretation.

Proposed resolution (April, 2006):

Change 7.6.3 [expr.cast] paragraph 6 as indicated:

The operand of a cast using the cast notation can be an rvalue of type “pointer to incomplete class type.” The destination type of a cast using the cast notation can be “pointer to incomplete class type.” In such cases, even if there is a inheritance relationship between the source and destination classes, whether the static_cast or reinterpret_cast interpretation is used is unspecified. If both the operand and destination types are class types and one or both are incomplete, it is unspecified whether the static_cast or the reinterpret_cast interpretation is used, even if there is an inheritance relationship between the two classes. [Note: For example, if the classes were defined later in the translation unit, a multi-pass compiler would be permitted to interpret a cast between pointers to the classes as if the class types were complete at that point. —end note]