我可以在调用纯虚函数时禁用异常吗?

时间:2013-02-04 15:12:08

标签: c++ gcc

我有一些看起来像这样的代码:

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

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

注意两个虚函数。使用arm-none-eabi-gcc编译它(以及我的其他代码),并与-fno-exceptions链接产生此输出:

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

使用方法存根替代纯虚函数再次运行它会产生:

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

这种巨大的差异似乎是由于例外。有什么办法可以防止这种情况发生吗?

2 个答案:

答案 0 :(得分:8)

此博客文章描述了这一点:Smaller binary size with C++ on baremetal (g++)

  

提供__cxa_pure_virtual()实施

     

如果您在任何地方使用纯虚函数但禁用了异常,则可以   注意你的代码突然再次膨胀。

     

这发生在我身上,需要一段时间才能追踪,哎呀!   检查最终二进制文件的汇编列表(来自objdump -h -C -S),它看起来像异常   回来了!

     

我试过的一件事就是与-nostdlib联系,完全拉出了libstdc ++   图片。我提供了malloc,realloc的虚拟实现,   free,以及我使用的一些其他stdlib函数,但随后avr32-g++   抱怨我以前没见过的东西:我失踪了   __cxa_pure_virtual()

     

Aha ,”我想,“这必须是它!”来源于此   在libstdc ++中找到的特定函数是对它的调用   std::terminate()seen here。那个电话在我可怜的AVR32上引起了一场可爱的聚会   闪存,在进入-fno-exceptions时踩踏。

     

无论如何,__cxa_pure_virtual()是您实际被调用的内容   调用纯虚函数。与newdelete一样,   这可能是你想要覆盖的东西,所以你自己   调试/跟踪代码可以为您提供有用的反馈。实施是   直截了当,只要确保它extern "C",所以名称不会被破坏:

extern "C" void __cxa_pure_virtual() { while(1); }

答案 1 :(得分:0)

我遇到了同样的问题,但实施 __ cxa_pure_virtual 并没有帮助我。

但我的解决方案是在 -fno-exceptions 选项旁添加 -fno-rtti