Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I disable exceptions for when a pure virtual function is called?

Tags:

c++

gcc

I have some code that looks like this:

class Writable {
public:
    virtual void putc(const char ch) = 0;
protected:
    virtual ~Writable() {};
};

class Readable {
public:
    virtual char getc() = 0;
protected:
    virtual ~Readable() {};
};

Notice the two virtual functions. Compiling this (along with my other code) using arm-none-eabi-gcc, and linking with -fno-exceptions produces this output:

arm-none-eabi-size  --format=berkeley bareCortexM.elf
   text    data     bss     dec     hex filename
 108948    2304    2372  113624   1bbd8 bareCortexM.elf

Running it again with method stubs in place of pure virtual functions yields:

arm-none-eabi-size  --format=berkeley bareCortexM.elf
   text    data     bss     dec     hex filename
  47340    2296     304   49940    c314 bareCortexM.elf

This huge difference seems to be due to exceptions. Is there any way that I can prevent this from happening?

like image 713
Eric Avatar asked Feb 04 '13 15:02

Eric


People also ask

What happens if pure virtual function is called?

A pure virtual function is declared, but not necessarily defined, by a base class. A class with a pure virtual function is "abstract" (as opposed to "concrete"), in that it's not possible to create instances of that class.

What happens if you call a pure virtual function C++?

You may call a virtual function as long as it is not a pure virtual function, and as long as you know that what you are calling is the method from the class itself and not expecting any polymorphism. Calling a pure virtual function from a constructor is undefined behaviour even if it has an implementation.

Is it compulsory to override a pure virtual function?

¶ Δ A pure virtual function is a function that must be overridden in a derived class and need not be defined.

Can pure virtual function be protected?

A virtual function can be private as C++ has access control, but not visibility control. As mentioned virtual functions can be overridden by the derived class but under all circumstances will only be called within the base class. Example: C++


1 Answers

This is described by this blog post: Smaller binary size with C++ on baremetal (g++)

Provide a __cxa_pure_virtual() implementation

If you use pure virtual functions anywhere but have disabled exceptions, you may notice your code suddenly inflate again.

This happened to me, and it took a while to track down, whoops!
Inspecting assembly listing of the final binary (from objdump -h -C -S), it looked like exceptions were coming back!

One thing I tried was linking with -nostdlib, completely pulling libstdc++ out of the picture. I provided dummy implementations of malloc, realloc, free, and a few other stdlib functions I used, but then avr32-g++ complained about something I hadn’t seen before: I was missing __cxa_pure_virtual().

Aha,” I thought, “this has to be it!” In the source of that particular function, found in libstdc++, is a call to std::terminate(), seen here. That call threw a lovely party all over my poor AVR32′s flash memory, trampling on -fno-exceptions on their way in.

Anyway, __cxa_pure_virtual() is what actually gets called when you call a pure virtual function. Like new and delete, this is probably something you want to override anyway so your own debug/trace code can give you useful feedback. The implementation is straightforward, just be sure to make it extern "C" so the name doesn’t get mangled:

extern "C" void __cxa_pure_virtual() { while(1); }
like image 149
Eric Avatar answered Sep 30 '22 17:09

Eric