简体   繁体   中英

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

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?

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); } 

I had same problem, but implementing __cxa_pure_virtual does not help me.

But solution for me was add -fno-rtti beside -fno-exceptions option.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM