Hacker News
When can the C++ compiler devirtualize a call?
fibonacci112358
|next
[-]
stevefan1999
|next
|previous
[-]
lowbloodsugar
|next
|previous
[-]
akoboldfrying
|next
|previous
[-]
Re "When we know the dynamic type", I made a similar assertion on HN years ago, and of course it turned out that there's a weird wrinkle:
If the code in your snippet is expanded to:
Derived d;
Base *p = &d;
any_external_func(); // Added
p->f();
where any_external_func() is defined in some other translation unit (and, I'm now fairly sure, Derived's ctor is also defined in another translation unit, or it transitively calls something that is), this would seem not to affect anything -- but in fact the compiler must not assume that p's dynamic type is still Derived by the final line. Why? Because the following insane sequence of events might have happened:1. d's ctor registers its this pointer in some global table.
2. Using this table, any_external_func() calls d's dtor and then overwrites it in place with a fresh instance of Base using placement new, which replaces everything, including its vtable, meaning that p->f() should call Base's version, not Derived's.
(It might be UB to call placement new on static or automatic storage holding an in-lifetime object, I don't know. If so, the above construction is moot -- but the closely analogous situation where we instead dynamically allocate dp = new Derived() still goes through, and is nearly as surprising.)