我想声明一个可以从多个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]
由1
file1中.但是,自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标准的工作解决方案对我来说是可以接受的.
您可以尝试的一件事:
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)