2015-06-02 13 views
5

Próbuję zbudować mały zestaw przypadków testowych dla kompilacji avr C++.Kiedy jest __cxa_deleted_virtual o nazwie

Istnieje kilka "wyjątkowych funkcji" dostarczanych zazwyczaj z biblioteki C++. Teraz chcę napisać program testowy, który produkuje ten niepoprawny kod, który musi łączyć się z __cxa_deleted_virtual.

Czy każdy może podać fragment kodu, który spowoduje połączenie z tą funkcją?

Nie mam pojęcia, jak utworzyć ten "błędny" kod.

+0

miałem ten sam problem z '__cxa_pure_virtual' jakiś czas temu, próbując debugowania nagły wzrost wielkości mojego (Embedded) Binary - mimo moich wysiłków w celu stworzenia minimalny program "buggy", nie mogłem go powiązać. Chciałbym zobaczyć w tym wglądzie guru C++. – Tibo

+0

__cxa_pure_virtual nie jest problemem, wystarczy wywołać funkcję wirtualną z konstruktora. Jest to zawsze błąd i powoduje wywołanie metody. – Klaus

+0

OK, mógłbym przeoczyć, dzięki. (W każdym razie sądziłem, że mój komentarz może dodać odpowiednie słowa kluczowe z punktu widzenia wyszukiwarki - np. Jeśli pojedynczy zasób zawierał informacje o "wyjątkowych funkcjach" w ogóle) – Tibo

Odpowiedz

2

Służy do wypełnienia vtable szczelinę funkcją wirtualną, która została zdefiniowana jako skasowane (. Powodem usunięty funkcją wirtualną uwzględnione w vtable jest this allows it to be later changed to non-deleted without breaking vtable layout)

struct B { virtual void f() = delete; }; 
struct D : B { virtual void f() = delete; }; 

Nie jestem świadomy żadnego sposobu, w jaki można go wywołać (względnie zdrowego) w C++, ponieważ jedyną rzeczą, która może zastąpić funkcję z usuniętą definicją, jest inna funkcja z usuniętą definicją ([class.virtual]/16) i każda próba wywołania funkcja z usuniętą definicją powoduje, że program jest źle sformułowany. Przypuszczam, że można powołać się widmo łamania ODR:

// TU 1 
struct B { virtual void f() = delete; virtual void g(); }; 
void B::g() { } // causes vtable to be emitted in this TU 

// TU 2 
struct B { virtual void f(); virtual void g(); }; 

void h(B* b) { b->f(); } 

int main() { 
    B b; 
    h(&b); 
} 
+0

Co oznacza skrót ODR? – Eric

+2

Co powiesz na kod wywołujący, używając przestarzałego nagłówka, który deklaruje, że funkcja nie jest usuwana? Może się to zdarzyć szczególnie łatwo, jeśli klasa jest dostarczana przez bibliotekę, która jest zbudowana niezależnie od kodu, który używa 'B'. – cmaster

+1

@cmaster ... co jest naruszeniem ODR. –