yet another

#include <cstdio>
struct I {
    virtual I *f() = 0;
};
struct A : virtual I {
    virtual I *f() { puts("A"); return this; }
};
struct B : virtual I {
    virtual I *f() { puts("B"); return this; }
    B(I *x) { x->f(); }
};
struct C : A, B {
    virtual I *f() { puts("C"); return this; }
    C() : A(), B(((A *)this)->f()) { ((A *)this)->f(); }
};
int main() {
    C c;
}

何が出るかな、何が(ry
運が悪ければ悪魔が出る。良ければ天使かもしれない。どちらでもなければ、たぶん出力は B, C で終わる。たとえば:*1

$ g++ test.cpp && ./a.out
A
B
C

*1:基底クラスの初期化が終わらないうちに、構築中のオブジェクトのメンバ関数をコンストラクタ初期化子(コロンの右側のリスト)の中から呼んでいるため未定義の挙動となる [12.6.2#8]。途中で B が出るのは、コンストラクタ実行中には構築中オブジェクトのメンバ関数のオーバーライドが無効になるせい [12.7#3]。この実行例で最初が A なのは、A の初期化の際に(vtable を差し替えることによって)無効にしたオーバーライドが、初期化完了後も復活していないからのようだ。