为什么 iostream 在 MCU 上占用这么多闪存 space?

Why does iostream take so much flash space on an MCU?

我使用 GCC 5.2.0 为 EFM32 MCU(基于 Cortex-M 内核)编译代码。当我想要 #include <iostream>.

时,我注意到代码大小大幅增加

例如,让我们为 EFM32WG "Wonder Gecko" 芯片编译以下代码:

#include "em_device.h"
#include "em_chip.h"
#include <iostream>

int main(void)
{
  CHIP_Init();

  while (1) {
  }
}

此代码将产生 172048 字节的代码,而没有 #include <iostream> 则只有 1440 字节。

我通常只使用 cout 进行调试输出(通过为 newlib 实现 _write 函数并将输出路由到 SWO 引脚),但看起来这种方法非常浪费,考虑到MCU 只有 256k 的闪存,只包括这个 header 将使代码用完大部分。

所以,我的问题是:为什么 包含 iostream header 使编译后的代码占用如此多的闪存 space?还有,有办法解决吗?

编辑:

编译器和链接器都是arm-none-eabi-g++(5.2.0版本),C库是nano C库(我觉得)

这是我的 C++ 编译器标志(不包括包含路径):

-g -gdwarf-2 -mcpu=cortex-m4 -mthumb '-DEFM32WG940F256=1' -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -mfpu=fpv4-sp-d16 -mfloat-abi=softfp

这是我的链接器标志:

-g -gdwarf-2 -mcpu=cortex-m4 -mthumb -T "${BuildArtifactFileBaseName}.ld" --specs=nosys.specs -Xlinker --gc-sections -Xlinker -Map="${BuildArtifactFileBaseName}.map" -mfpu=fpv4-sp-d16 -mfloat-abi=softfp --specs=nano.specs

我尝试了优化和不优化,但生成的代码大小保持大致相同(优化后的大小可能小 1k)。

编辑 2

-fno-rtti-fno-exceptions 对代码大小也没有帮助。

虽然编译器确实尝试消除完整的包含或其中未使用的部分,但这有时会失败。一些 headers 只是被包括在内 导致代码为 运行 - 这意味着即使您没有引用 header 中包含的任何内容,编译器也不能随意从中删除代码。

<iostream> 就是这样一个例子,因为它声明了一些全局 objects 其 在调用 main 之前,构造函数是 运行。它的包含将大致 将 STM32 的二进制大小增加 140kB。

您可以在 github.

上查看 gcc 开发人员的这种行为和推理

解决方案是避免在微控制器上使用 C 提供的打印功能,例如 printf()