如何强制gcc编译器/链接器从可执行的未使用静态数组中删除

时间:2019-03-19 10:36:30

标签: c++ arrays static g++ template-specialization

我有一个大数组uint8_t [95][5],其中包含7x5位图的各种字符(每个字节中的1位未使用)。我只使用了这95个字符中的几个,但是完整的静态数组仍然存储在程序存储器中。

我正在使用AVR,它的程序存储器有限,因此每个字节都很重要!因此,我尝试将数组重写为许多模板专用类(请参见下文),但是并不能解决问题。当我导入包含所有定义的头文件时,所有字符都将成为可执行文件的一部分,无论程序中是否使用了它们。

例如,以下代码

#include <stdint.h>
template <char C> struct BitMap { static uint8_t cols[5]; };
template <> uint8_t BitMap<'3'>::cols[] = {0xFF,0xFC,0xAB};
int main() { return 0; }

g++ -Os编译生成

main:
    xor     eax, eax
    ret
BitMap<(char)51>::cols:
    .byte   -1
    .byte   -4
    .byte   -85
    .zero   2

由于该静态数组未在程序中使用,有没有办法指示编译器/链接器摆脱它?另外,是否可以执行任何代码技巧,以便仅在使用数组时实例化该数组?

2 个答案:

答案 0 :(得分:1)

您已经基本描述了静态库链接的工作原理。

将对象作为单个模块放入静态库中。与静态库链接。该模块将被拉入可执行文件,并成为可执行文件的一部分,只有在代码中的某个位置引用了数组的符号时才可以。

各种C ++链接器有时在解析对静态库中定义的外部符号的纯数据引用时遇到问题。可能需要修改链接器。

答案 1 :(得分:1)

一种方法可能是声明模板函数的特化,每个特化返回数据,并且未编译的内联函数将不被编译;但是,这可能意味着该数组是动态创建的。您可以将字符字体定义打包到int64中,并使其成为纯代码吗?