Title
Old-style casts between incomplete class types
Status
cd1
Section
7.6.3 [expr.cast]
Submitter
comp.std.c++

Created on 2005-05-19.00:00:00 last changed 161 months ago

Messages

Date: 2007-04-15.00:00:00

[Voted into WP at April, 2007 meeting.]

Date: 2006-04-15.00:00:00

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]
Date: 2005-05-19.00:00:00

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.

History
Date User Action Args
2008-10-05 00:00:00adminsetstatus: wp -> cd1
2007-08-05 00:00:00adminsetstatus: dr -> wp
2007-05-06 00:00:00adminsetmessages: + msg1500
2007-05-06 00:00:00adminsetstatus: ready -> dr
2006-11-05 00:00:00adminsetstatus: review -> ready
2005-10-22 00:00:00adminsetmessages: + msg1233
2005-10-22 00:00:00adminsetstatus: open -> review
2005-05-19 00:00:00admincreate