when is __cxa_deleted_virtual called
Asked Answered
B

1

7

I try to build a little test case set for avr c++ builds.

There are some "exceptional functions" provided typically from the c++ library. Now I want to write a test program which produces this wrong code which must link to __cxa_deleted_virtual.

Can anyone provide a code snippet which results in linking to that function?

I have actually no idea how to produce this "buggy" code.

Barogram answered 2/6, 2015 at 12:48 Comment(5)
I had the same problem with __cxa_pure_virtual a while ago, trying to debug the sudden increase in size of my (embedded) binary - despite my efforts to create a minimal "buggy" program, I couldn't have it linked in. I'd love to see C++ gurus' insight on this.Glochidiate
__cxa_pure_virtual is no problem, simply call a virtual function from the constructor. This is always a failure and results in calling the method.Barogram
ok, I might have overlooked that, thanks. (Anyway I was thinking my comment could add relevant keywords from a search engine standpoint - e.g. if a single resource contained info for "exceptional functions" in general)Glochidiate
Interesting llvm does not mention the existance of this functionMany
I tried struct base { virtual void f() {} }; struct derived : base { void f() = delete; }; int main() { derived d; base& b = d; b.f(); }, but that refuses to compile. I wonder if you need a compiler which doesn't reject that code?Diptych
Y
4

It's used to fill the vtable slot of a virtual function that has been defined as deleted:

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

(The reason a deleted virtual function is included in the vtable is that this allows it to be later changed to non-deleted without breaking vtable layout.)

I'm not aware of any way it could actually get called in (relatively sane) C++, since the only thing that can override a function with a deleted definition is another function with a deleted definition ([class.virtual]/16), and any attempt to call a function with a deleted definition renders the program ill-formed. I suppose you can invoke the specter of ODR violations:

// 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);
}
Yaupon answered 2/1, 2017 at 13:37 Comment(5)
What does ODR stand for?Many
How about the calling code using an outdated header that declares the function as not being deleted? This can happen especially easily if the class is provided by a library which is built independently of the code that uses B.Follmer
@cmaster ...which is an ODR violation.Yaupon
@Many The one definition rule.Yaupon
@Yaupon Of course, it is an ODR violation. Nevertheless, it is a violation that happens in the wild, leading to such nasty effects as virtual function calls ending up calling the wrong function, etc. (I actually had that once: built a library, forgot to install it, linked code compiled with newer headers against the outdated .so file, had a lot of fun debugging the result...). In the case of a deleted function, such an ODR violation might result in __cxa_deleted_virtual being called. Of course, if that function ends up being called, it is the build system that is broken and needs fixing.Follmer

© 2022 - 2024 — McMap. All rights reserved.