添加虚拟析构函数会增加代码大小

时间:2017-07-21 17:33:11

标签: c++ gcc arm

我用最新的arm-none-eabi-gcc 6.3在手臂皮质m3上使用c ++进行愚弄。 我创建了一个虚拟类并创建了该类的全局对象:

class B
{};

class A : B
{
public:
    A()
    {
        RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
        GPIOC->CRH = 1;
        GPIOC->ODR |= 1<<8;    
    }

    virtual void foo()
    {}

    virtual ~A()
    {}
};

A a;

int main(void) { while(1); }

此代码编译为1620个字节。如果我删除虚拟dtor,它编译为1304字节。这是一个显而易见的差异。

我去查看了assembly和.map文件,看到如果我使用虚拟dtor,许多不同的运行时函数都链接到我的二进制文件。有malloc和free和_static_initialization_and_destruction等等。

奇怪的是:我不明白他们是怎么称呼的? Main叫做这样:

 8000260:   d3f9        bcc.n   8000256 <FillZerobss>
 8000262:   f000 f89f   bl  80003a4 <SystemInit>
 8000266:   f000 f957   bl  8000518 <__libc_init_array>
 800026a:   f000 f865   bl  8000338 <main>
 800026e:   4770        bx  lr

从main返回后(顺便说一句,从不发生)执行只是坐在bx lr上,它一直跳到同一个地址。

因此,我无法看到要调用静态对象取消初始化的路径。为什么它不能作为无法访问的代码进行优化?

我这样编译: arm-none-eabi-g++ -c -fmessage-length=0 -mcpu=cortex-m3 -mthumb -fdata-sections -ffunction-sections -fno-rtti -fno-exceptions -fno-threadsafe-staticsarm-none-eabi-g++ -mcpu=cortex-m3 -mthumb --specs=nosys.specs --specs=nano.specs -Wl,--gc-sections -T "${ProjDirPath}/src/Startup/STM32F100XB_FLASH.ld" -ffreestanding

这样的链接

我尝试添加-fno-use-cxa-atexit或制作一个虚拟__cxa_atexit - 它确实使二进制稍微更小(这甚至比没有效果更奇怪)。

有没有办法完全禁用静态对象的破坏?

更新:

  • 添加-Os使代码缩小但是有/无虚拟dtor(1244对1040字节)仍有差异,所以问题仍然存在。
  • 这里是使用-S with dtor编译的输出,without dtor

1 个答案:

答案 0 :(得分:0)

如果没有整个程序优化,则不清楚析构函数是否实际无法访问。可能有另一个带有构造函数的翻译单元,该构造函数生成一个稍后调用exit函数的线程。