St.Antario
St.Antario

Reputation: 27385

Ill-formed static-cast interpretation

I've come across with the follwing code (sec. 5.4/4 N3797):

struct A { };
struct I1 : A { };
struct I2 : A { };
struct D : I1, I2 { };
A* foo( D* p ) {
    return (A*)( p ); // ill-formed static_cast interpretation
}

I have been trying to understand the example, but I can't. I haven't used static_cast in the example at all. How does it relate to static_cast. In general, would you explain the point of the error.

Upvotes: 3

Views: 106

Answers (1)

jxh
jxh

Reputation: 70392

The "C style cast" is called "explicit type conversion", and is discussed in §5.4 if the C.11 standard. In ¶4:

The conversions performed by
— a const_cast (5.2.11),
— a static_cast (5.2.9),
— a static_cast followed by a const_cast,
— a reinterpret_cast (5.2.10), or
— a reinterpret_cast followed by a const_cast,
can be performed using the cast notation of explicit type conversion.

Which is basically saying a static_cast may be the result of a cast expression. It then lists some conditions under which it is a valid static_cast, and the example you cite was an example when it was invalid. Just before that example was the following text (the very end of ¶4):

If a conversion can be interpreted in more than one of the ways listed above, the interpretation that appears first in the list is used, even if a cast resulting from that interpretation is ill-formed. If a conversion can be interpreted in more than one way as a static_cast followed by a const_cast, the conversion is ill-formed.

The reason the example listed is ill-formed is because both I1 and I2 do non-virtual inheritance from A. Thus, D, which uses multiple inheritance on I1 and I2 will have two A instances within it, and so trying to cast a D * to an A * has more than one interpretation. The programmer needs to specify which A * instance should result to avoid an ill-formed conversion.

ASCII art alert:

+---+          +---+
| A |          | A |
+---+          +---+
  |              |
 /_\            /_\
  |              |
+----+         +----+
| I1 |         | I2 |
+----+         +----+
  |              |
  +------.-------+
         |
        /_\
         |
       +---+
       | D |
       +---+

Upvotes: 3

Related Questions