添加printf为何导致RISCV程序数据段异常暴增?
针对RISCV程序数据段暴增问题的解答
现象是否正常?
这不正常,本质是编译器优化逻辑因printf的引入发生了变化:
- 没加
printf时,编译器会把未被直接调用的静态数组(或初始化全为0的静态数组)放到.bss段——这个段不占镜像空间,仅在程序运行时才申请内存; - 一旦用
printf打印某个静态数组,编译器会默认头文件里声明的所有静态数组都存在被间接引用的可能,于是把它们全塞进.data段。而.data段直接占用镜像大小和运行时内存,因此出现数据段暴增的情况。
降低数据内存占用的方法
- 强制指定段属性:对不需要放入
.data段的静态数组,用__attribute__((section(".bss")))强制编译器将其归入.bss段,示例代码:static int temp_arr[2048] __attribute__((section(".bss"))); - 开启链接时垃圾回收:编译时添加
-ffunction-sections -fdata-sections参数,链接时添加-Wl,--gc-sections参数,让编译器和链接器自动剔除未被实际用到的静态数据和函数。 - 规范数组初始化:如果静态数组需要全0初始化,不要写
= {0}这类显式初始化代码,让编译器自动将其归入.bss段;显式初始化会被强制放到.data段。 - 替换静态分配为动态分配:对实际使用元素较少的静态数组,改用
malloc动态申请内存,用完后用free释放,减少静态内存的固定占用。
内容的提问来源于stack exchange,提问作者Dresult
相关产品推荐
相关产品推荐

