我有一些代码看起来像这样:
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++ 更小的二进制大小 (g++) http://elegantinvention.com/blog/information/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()
.
“Aha,“ 我想, ”一定是这样!” 在这个来源中
libstdc++ 中的特定函数是对std::terminate()
, 见过
这里 http://gcc.gnu.org/svn/gcc/tags/gcc_4_4_3_release/libstdc++-v3/libsupc++/pure.cc。那通电话给我可怜的 AVR32 带来了一场可爱的派对
闪存,践踏-fno-exceptions
在他们进来的路上。
Anyway, __cxa_pure_virtual()
是当你实际被调用的
调用纯虚函数。喜欢new
and delete
,
无论如何,这可能是您想要覆盖的内容,因此您自己的
调试/跟踪代码可以为您提供有用的反馈。实施是
简单,只要确保做到即可extern "C"
所以名字不会被破坏:
extern "C" void __cxa_pure_virtual() { while(1); }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)