-1

First two exceptions of strict aliasing rule on cppreference.com says:

  • AliasedType is (possibly cv-qualified) DynamicType
  • AliasedType and DynamicType are both (possibly multi-level, possibly cv-qualified at each level) pointers to the same type T (since C++11)

I don't clearly understand the difference between these cases. For instance:

struct B { virtual ~B() {} };
struct D : B {};

B* b = new D;
reinterpret_cast<D*>(b);

Is the code above suitable for both cases or not?

As far as I see AliasedType and DynamicType both are D (1st case) and they are pointers to same type D.

If I’m wrong could you provide examples for each separate case and explain the difference more clearly?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
αλεχολυτ
  • 4,792
  • 1
  • 35
  • 71
  • cppreference is wrong here. You cannot `reinterpret_cast` a base pointer to a derived pointer or back, and then dereference the converted pointer, regardless of the dynamic type of the object. – n. m. could be an AI Sep 23 '17 at 10:12
  • @n.m. could you provide any reference to the standard? – αλεχολυτ Sep 23 '17 at 11:38
  • 6.9.2p4. "Two objects a and b are pointer-interconvertible if ..." Only the first base class subobject is allowed and only if the object has standard layout. – n. m. could be an AI Sep 23 '17 at 12:03
  • Why use `reinterpret_cast` when `static_cast` or `dynamic_cast` (run time checked) would work? – Bo Persson Sep 23 '17 at 13:00
  • @BoPersson my interest is mostly on theoretic part here. In production code I would prefer more obvious cast. – αλεχολυτ Sep 23 '17 at 14:15
  • @n.m. [several answers](https://stackoverflow.com/search?q=AliasedType+is+%28possibly+cv-qualified%29+DynamicType+is%3Aa) (mostly from Jonathan Mee) refer to that cppreference page. Maybe they should be reviewed? – αλεχολυτ Sep 23 '17 at 14:37
  • @n.m. what about 6.10p8? Looks like that paragraph is an source for cppreference page. – αλεχολυτ Sep 23 '17 at 15:02
  • The [talk page](http://en.cppreference.com/w/Talk:cpp/language/reinterpret_cast) basically says the main page is wrong and needs to be reviewed, so yeah. – n. m. could be an AI Sep 23 '17 at 16:43
  • 1
    6.10p8 doesn't give you a license to reinterpret_cast anything. It says you can access an object through its dynamic pointer type *or* through a pointer to one of its base classes. It doesn't say they have to be convertible one to another with a reinterpret_cast (and it could not have possibly say that because it is night impossible to implement inheritance and reinterpret cast this way, or at least no existing implementation implements them this way). – n. m. could be an AI Sep 23 '17 at 17:09

1 Answers1

2

To understand the statement there, you have to realize that DynamicType refers to the type of the object, and AliasedType to the type of the expression used to access that value. But the cast itself is not from DynamicType to AliasedType, but from DynamicType* to AliasedType*.

Now, C++ has multi-level pointers. DynamicType can be some A* and AliasedType can be some B*, possibly cv-qualified. Hence, DynamicType* would be A**. This is why you need the second case. AliasedType could be a A const*, which is different from A*. Hence, it's not covered under the first rule (A const* is not a cv-qualified version of A*, unlike A* const).

Now, as for your code: The DynamicType of your object is D, which is very obvious from new D. D is not a pointer type, it's a class type. This means only cv-qualifed variants can alias it: volatile D, const D, and const volatile D.

However, you don't have a pointer to that D object, you have a pointer to its B sub-object. This sub-object can be aliased by a B const etc.

What you are doing is trying to gain access the B sub-object using an AliasedType of D. That isn't going to work - D is not a cv-qualified B. They're related by inheritance, not cv-qualification.

MSalters
  • 173,980
  • 10
  • 155
  • 350