这是我的代码:
#define MSK 0x0F
#define UNT 1
#define N 3000000000
unsigned char aln[1+N];
unsigned char pileup[1+N];
void set(unsigned long i)
{
if ((aln[i] & MSK) != MSK ) {
aln[i] += UNT;
}
}
int main(void) {}
当我尝试编译它时,编译器抱怨如下:
tmp/ccJ4IgSa.o: In function `set':
bitmacs.c:(.text+0xf): relocation truncated to fit: R_X86_64_32S against symbol `aln' defined in COMMON \
section in /tmp/ccJ4IgSa.o
bitmacs.c:(.text+0x29): relocation truncated to fit: R_X86_64_32S against symbol `aln' defined in COMMON\
section in /tmp/ccJ4IgSa.o
bitmacs.c:(.text+0x32): relocation truncated to fit: R_X86_64_32S against symbol `aln' defined in COMMON\
section in /tmp/ccJ4IgSa.o
我认为原因可能是N
太大了,因为如果我将N改为2000000000它可以成功编译。但我需要3000000000作为N的值..
有人对此有所了解吗?
答案 0 :(得分:6)
根据您的原始问题:使用整数文字后缀 UL (或类似)强制存储类型为N:
#define N 3000000000UL
然而,(根据你对HLundvall的回答的评论)relocation truncated to fit
错误显然不是由于这个 - 它可能(正如Mystical和Matt Lacey所说)只是太大而不适合该段。
顺便说一句,如果你问一个单独的问题,解释你想要用你的巨大数组完成什么,有人可能会建议一个更好的解决方案(更有可能适合内存)
例如:
答案 1 :(得分:5)
忽略数字文字不正确的“正式”问题(请参阅其他答案以获得正确的语法),这里的关键点是分配3 GB静态/全局是一个非常糟糕的主意阵列。
大多数平台上的 static
和全局 1 变量直接从可执行映像映射,这意味着您的可执行文件必须大到3 GB,这甚至是相当大的对于当前的标准。即使在某些平台上可能会解除此限制(请参阅注释),您也无法控制如何处理分配失败。
最重要的是,全局变量并不适用于这么大的东西,并且您可能会发现链接器(例如您找到的)和加载器强加的任意限制问题。相反,您应该使用malloc
,new
或某些特定于平台的函数在堆上分配大于几KB的任何内容,在运行时优雅地处理可能的故障。
但是,请记住,对于在几乎任何32位操作系统下运行的应用程序,根据您的要求,不可能获得3 GB的连续内存,并且完全不可能获得多个这些数组(= 4 GB的连续内存)而不依赖于特定于平台的技巧(例如,在给定时刻仅映射内存中数组的特定部分)。
另外,您确定自从程序开始运行以来确实需要所有连续的内存吗?是不是有一些更好的数据结构/算法可以避免分配所有内存?
答案 2 :(得分:1)
要输入unsigned long use类型的数字常量:
#define N 3000000000UL
答案 3 :(得分:1)
问题是gcc(默认情况下)使用pc相对访问来获取x86_64目标上的静态数据对象的地址,并且这些访问限制为最多2 ^ 31个字节。因此,如果符号最终放置距离访问它的代码超过2GB,当它尝试使用太大而不适合32位空间的偏移量时,最终会出现此链接错误。指令。
您可以使用gcc的-mcmodel=large
选项来避免此问题。这告诉它不要假设它可以使用32位PC相对偏移来访问符号(除其他外)
请注意,常量文字的类型后缀几乎是无关紧要的 - 对于int来说太大的常量字面值将自动变为长(或者甚至很长,如果需要)而没有任何后缀。见C99规范的6.4.4.1.5。
答案 4 :(得分:-1)
您的可执行文件正在尝试将对象放在内存中超过4GB标记,这是不允许的。请看这个链接:http://www.technovelty.org/code/c/relocation-truncated.html。
从文章中可以看出:“如果你看到这个并且你不是手工编码,你可能想要查看gcc的-mmodel参数。”