【问题标题】:Can I disable exceptions for when a pure virtual function is called?我可以在调用纯虚函数时禁用异常吗?
【发布时间】:2013-01-19 07:46:07
【问题描述】:

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

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

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

【问题讨论】:

    标签: c++ gcc


    【解决方案1】:

    这篇博文对此进行了描述:Smaller binary size with C++ on baremetal (g++)

    提供__cxa_pure_virtual() 实现

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

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

    我尝试过的一件事是与 -nostdlib 链接,将 libstdc++ 完全退出 图片。我提供了 malloc、realloc、 免费的,以及我使用的其他一些 stdlib 函数,但后来 avr32-g++ 抱怨我以前没见过的东西:我失踪了 __cxa_pure_virtual().

    啊哈,”我想,“这就是它!” 在 libstdc++ 中找到的特定函数是对 std::terminate()seen here。那通电话在我可怜的 AVR32 上掀起了一场可爱的派对 闪存,在他们进来的路上践踏了-fno-exceptions

    不管怎样,__cxa_pure_virtual() 是你实际调用的 调用纯虚函数。喜欢newdelete, 这可能是你想要覆盖的东西,所以你自己的 调试/跟踪代码可以为您提供有用的反馈。实现是 直截了当,只要确保将其设为 extern "C",这样名称就不会被破坏:

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

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,但实施 __cxa_pure_virtual 对我没有帮助。

      但对我来说,解决方案是在 -fno-exceptions 选项旁边添加 -fno-rtti

      【讨论】:

        猜你喜欢
        • 2019-12-14
        • 2016-02-05
        • 2010-10-07
        • 1970-01-01
        • 2014-09-02
        • 2018-08-05
        • 2017-01-22
        • 2023-03-30
        • 2011-08-06
        相关资源
        最近更新 更多