I want to declare a constant array which can be accessed from multiple C files and whose content can be inlined by the compiler, without duplicating the memory in multiple compilation units. Performance is critical in my application.
Exhibit 1:
header.h:
static const int arr[2] = { 1, 2 };
file1.c:
#include "header.h"
void file1() { printf("%d\n", arr[0]); }
file2.c:
#include "header.h"
int file2() { for (int i = 0; i < 2; i++) printf("%d\n", arr[i]); }
In that case, the compiler can replace arr[0] by 1 in file1. However, since arr is declared static const, its memory is duplicated in both C files. AFAIK the C standard requires the array addresses to be different in both files. I have verified this under Linux by printing out the addresses. No linker consolidation occurs even with -fmerge-all-constants in gcc.
Exhibit 2:
header.h:
extern const int arr[2];
file1.c:
#include "header.h"
void file1() { printf("%d\n", arr[0]); }
file2.c:
#include "header.h"
const int arr[2] = { 1, 2 };
int file2() { for (int i = 0; i < 2; i++) printf("%d\n", arr[i]); }
In that case, no memory duplication occurs but arr[0] is not inlined.
I consider the visibility scope defined by the C standard to be flawed. As such, a working solution under Linux/gcc which violates the C standard is acceptable to me.
One thing you might try:
Now the array still exists in every *.o object, but when those objects are linked together in a program, GNU
ldwill reduce them to just one common chunk of data.If you don’t already have such a thing, you may want in some common header file: