0

I have a big array uint8_t [95][5] containing the 7x5 bitmaps various characters (1 bit in each byte is unused). I am only using a few of these 95 characters, but the full static array is stored in program memory anyway.

I am working with an AVR, which has limited program memory, hence every byte counts! So I tried to rewrite the array as a number of template specialized classes (see below), but it did not solve the problem. When I import the header file containing all definitions, all characters become part of my executable, regardless if they are used or not in the program.

For exmaple, the following code

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

compiled with g++ -Os generates

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

Since this static array is not used in the program, is there a way to instruct the compiler/linker to get rid of it? Alternatively, is there any code trick I can do so that the array is instantiated only if I use it?

Fabio
  • 1,790
  • 8
  • 24
  • Try writing "normal" templates without getting clever with explicit specializations. Templates are only instantiated when used, so you basically already don't get dead code by construction. Explicit specializations break that simplicity. – Kerrek SB Mar 19 '19 at 10:44
  • Have you tried compiling with -fdata-sections and linking with -Wl,--as-needed (or just --as-needed when using ld directly)? – PaulR Mar 19 '19 at 12:14
  • Indeed I found the solution following the duplicate question link: `-fdata-sections` does the trick – Fabio Mar 19 '19 at 16:44

2 Answers2

1

You've basically described how static library linking works.

Put the object into a static library as a single module. Link with the static library. The module will get pulled into the executable, and become a part of the executable, only if the array's symbol is referenced somewhere in the code.

Various C++ linkers sometimes have problems resolving data-only references to external symbols defined in static libraries. Some tinkering with the linker may be necessary.

Sam Varshavchik
  • 84,126
  • 5
  • 57
  • 106
1

One way might be to declare specialisations of a template function, each of which return the data, and the unused inline functions would not be compiled; however that might mean the array is created on the fly. Could you package your character font definitions into an int64, and make it pure code?

Gem Taylor
  • 4,767
  • 1
  • 5
  • 25
  • Passing to the compiler `-fdata-sections` fixed the problem. However, these are both good ideas. In particular, I tried using template functions and it works beautifully. – Fabio Mar 20 '19 at 02:22