如何使用宏作为无符号长号?

Han*_*Sun 5 c c++ macros

这是我的代码:

#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) {}
Run Code Online (Sandbox Code Playgroud)

当我尝试编译它时,编译器抱怨如下:

 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
Run Code Online (Sandbox Code Playgroud)

我认为原因可能N是太大,因为它可以成功编译,如果我将N改为2000000000.但我需要3000000000作为N的值..

有人有这个想法吗?

Use*_*ess 6

根据您的原始问题:使用整数文字后缀UL(或类似)强制存储类型为N:

#define N 3000000000UL
Run Code Online (Sandbox Code Playgroud)

然而,(根据您对HLundvall的答案的评论),relocation truncated to fit错误显然不是由于这个 - 它可能(正如Mystical和Matt Lacey所说)只是太大而不适合细分市场.


顺便说一句,如果你问一个单独的问题,解释你想用你的巨大阵列完成什么,有人可能会建议一个更好的解决方案(更有可能适合内存)

例如:

  • 您的示例代码仅使用所示代码中每个字节的低半字节:您可以将其打包为一半大小(这无疑是太大了)
  • 根据您的访问模式,您可以将阵列保留在磁盘上并在内存中缓存一个工作子集
  • 如果我们知道您需要什么,可能会有更好的整体算法和数据结构


Mat*_*lia 5

忽略数字文字不正确类型的"形式"问题(请参阅其他答案以获得正确的语法),这里的关键点是分配3 GB静态/全局数组是一个非常糟糕的主意.

static大多数平台上的全局1变量直接从可执行映像映射,这意味着您的可执行文件必须大到3 GB,即使对于当前标准来说也是如此.即使在某些平台上可能会解除此限制(请参阅注释),您也无法控制如何处理分配失败.

最重要的是,全局变量不适用于这么大的东西,并且您可能会发现链接器(例如您找到的)和加载器强加的任意限制的问题.相反,你应该分配什么,这比在堆上几KB更大,使用malloc,new或某些特定于平台的功能,优雅地处理在运行时可能出现的故障.

但是,请记住,对于在几乎任何32位操作系统下运行的应用程序,不可能根据您的要求获得3 GB的连续内存,并且完全不可能获得多个这些数组(=超过4 GB的数据)连续的内存)而不依赖于特定于平台的技巧(例如,在给定时刻仅映射内存中数组的特定部分).

此外,您确定自从程序开始运行以来确实需要所有连续的内存吗?是不是有一些更好的数据结构/算法可以避免分配所有内存?


  1. 通常,标准使用静态存储持续时间调用变量.