4

I was wondering what the standard says about the safety of the following code:

class A { int v; };
class B: public A { }; // no added data member

A a;
B& b = static_cast<B&>(a);

Obviously the runtime type of a is A, not B, so the cast is not really type safe. However, since there was no member added and nothing is virtual, IMO the memory layout of the classes should be the same and this should work (maybe it would be nicer to write reinterpret_cast to indicate this behaviour?). My guess would be that this is UB, but would work with any compiler. Or is this actually well defined? Or rather dangerous?

Also, would anything change if B had some additional non-virtual member methods? Again, intuitively I would say no, but I wonder what the standard has to say about this.

Zong
  • 6,160
  • 5
  • 32
  • 46
Janick Bernet
  • 20,544
  • 2
  • 29
  • 55
  • duplicate http://stackoverflow.com/questions/6322949/downcasting-using-the-static-cast-in-c – user2485710 Jan 27 '14 at 02:56
  • My question explicitly does not involve virtual members, where the referenced one does. I'm not sure this changes anything in regards to the quoted standard excerpt, but I think it might change something in regards to whether this is generally safe or not. – Janick Bernet Jan 27 '14 at 03:05
  • you example qualifies for UB: what more do you need to know ? – user2485710 Jan 27 '14 at 03:06
  • Whether this is still safe or not. IMO the use of static_cast like this is the same as reinterpret_cast or a c-style cast, which is also part of my question, so I think its as UB as it generally is for those kinds o casts, which is IMO safe for this scenario. This is not addressed in the referenced duplicate at all. – Janick Bernet Jan 27 '14 at 03:10
  • @JanickBernet: A good piece of advice would be not to depend on behavior not mandated by the standard. A different compiler or platform might break your code. Will it work in most cases: yes, are you willing to potentially sacrifice the correctness of your program using this type of construct? – David Rodríguez - dribeas Jan 27 '14 at 03:42

1 Answers1

6

It's undefined behavior, regardless of whether there's virtual function or not. The standard says clearly,

If the prvalue of type "pointer to cv1 B" points to a B that is actually a subobject of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the result of the cast is undefined.

user534498
  • 3,926
  • 5
  • 27
  • 52
  • Ok. That's clear enough. I'd still would like to know whether this would generally be safe or not, though, and whether there is any difference in regards to the UB if it was changed to reinterpret_cast or c-cast? – Janick Bernet Jan 27 '14 at 03:35
  • @JanickBernet: using `reinterpret_cast` won't make a difference in this particular case. It is undefined behavior in either case. – David Rodríguez - dribeas Jan 27 '14 at 03:43
  • That's what I would have assumed. Now then for me the final question is: When is `reinterpret_cast` safe? I think the definition has something to do with standard layout, which probably would hold for the given example as long as the type of `v` is not complex? – Janick Bernet Jan 27 '14 at 06:45
  • I think this http://stackoverflow.com/questions/7762929/safety-of-casting-between-pointers-of-two-identical-classes/7762964#7762964 answers my final question. According to the standard what I'm doing seems definitely not well defined, though I still don't see any reason for it to not work at runtime... – Janick Bernet Jan 27 '14 at 06:50