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()
implementationIf 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 (fromobjdump -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 thenavr32-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. Likenew
anddelete
, 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 itextern "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.