Adding a virtual destructor bloats code size

Viewed 251

I'm fooling around with c++ on arm cortex m3 with latest available arm-none-eabi-gcc 6.3. I made a dummy class and created a global object of that class:

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); }

This code compiles to 1620 bytes. If I remove virtual dtor it compiles to 1304 bytes. That's a palpable difference.

I went and looked into assembly and .map file and saw that many different runtime functions are being linked to my binary if I use virtual dtor. There's malloc and free and _static_initialization_and_destruction and so on.

The strange thing is: I do not understand how are they called? Main is called like this:

 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

After return from main (which never happens, by the way) execution just sits there on bx lr, it keeps jumping to the same address.

So I can't see a path for static object deinitialization to be called. Why isn't it optimized away as unreachable code?

I compile like this: arm-none-eabi-g++ -c -fmessage-length=0 -mcpu=cortex-m3 -mthumb -fdata-sections -ffunction-sections -fno-rtti -fno-exceptions -fno-threadsafe-statics and link like this arm-none-eabi-g++ -mcpu=cortex-m3 -mthumb --specs=nosys.specs --specs=nano.specs -Wl,--gc-sections -T "${ProjDirPath}/src/Startup/STM32F100XB_FLASH.ld" -ffreestanding

I tried adding -fno-use-cxa-atexit or making a dummy __cxa_atexit - and it does make binary slightly smaller (which is even weirder than no effect at all).

Is there any way to disable destruction of static objects completely?

UPDATE:

  • adding -Os made code shrink but there is still a difference with/without virtual dtor (1244 vs 1040 bytes ) so the question remains.
  • here's the output of compiling with -S with dtor, without dtor
1 Answers
Related