Inlinable常量C数组,没有内存重复

13 c arrays linker constants

我想声明一个可以从多个C文件访问的常量数组,其内容可以由编译器内联,而不需要在多个编译单元中复制内存.性能在我的应用中至关重要.

图表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]); }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,编译器可以替代arr[0]1file1中.但是,自arr声明以来static const,它的内存在两个C文件中都是重复的.AFAIK C标准要求两个文件中的阵列地址不同.我在Linux下通过打印地址验证了这一点.即使-fmerge-all-constants在gcc中也不会发生链接器合并.

图表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]); }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,不会发生内存重复,但arr[0]不会内联.

我认为C标准定义的可见范围是有缺陷的.因此,Linux/gcc下违反C标准的工作解决方案对我来说是可以接受的.

asc*_*ler 2

您可以尝试的一件事:

const int arr[2] __attribute__((weak)) = { 1, 2 };
Run Code Online (Sandbox Code Playgroud)

现在,数组仍然存在于每个 *.o 对象中,但是当这些对象在程序中链接在一起时,GNUld会将它们减少为一个公共数据块。

如果您还没有这样的东西,您可能需要一些通用的头文件:

#ifndef __GNUC__
#define __attribute__(x)
#endif
Run Code Online (Sandbox Code Playgroud)