【问题标题】:C compiling: relocation truncated to fit R_X86_64_PC32 against symbolC 编译:重定位被截断以适合 R_X86_64_PC32 对符号
【发布时间】:2019-08-02 18:48:34
【问题描述】:
/* my program
   author/date:  me/now
*/

# include <stdio.h>

# define XX    1000
# define YY    20000       /* value of 1000 is ok */
# define ZZ    6000

/* global variable declaration */

int some_variable_this;
int some_variable_that;
double data[XX][YY][ZZ];

static void some_procedure_this ( void )
{
}

static void some_procedure_that ( void )
{
}

int main ( int argc, char *argv[] )
{
}

编写一个快速的 C 程序来重新格式化一些数据。 通过gcc myprogram.c 编译时,如果我使全局data 数组太大,我会得到编译器错误:

relocation truncated to fit R_X86_64_PC32 against symbol 'some_variable_this'
relocation truncated to fit R_X86_64_PC32 against symbol 'some_variable_that'

我的目标是编写一个快速的 c 代码来重新格式化一些数据。

  • 这个R_X86_64_PC32是什么意思?
  • 我可以使用编译器标志来解决这个问题吗?
  • 有没有更好的方法在 C 中编写此代码,同时仍保持编写代码的速度和简单性以提高人类可读性?

如果重要的话,这在 linux 中的 gcc 4.3.4 上。

【问题讨论】:

  • 为什么thisthat 被声明为ints 和void 函数?
  • 请注意,1000 * 20000 * 6000 * sizeof(double) 仅比 1 TiB 主内存少一点点。对于数组来说有点大。你确定尺寸合适吗?如果你真的有一台主存为 TB 的机器,我有点嫉妒。
  • 您说1000 可以,但20000 不行。我认为该数组的大小是您问题的主要因素。你可以使用动态内存分配(malloc() 等)来避免巨大的静态大小的数组吗?
  • double (*data)[YY][ZZ] = 0 定义了一个指向数组的指针(如果有多个源文件,则在头文件中声明 extern double (*data)[YY][ZZ]; — 这意味着(XX 和)YYZZ 将也可以在标题中定义)。在您的main() 程序中,添加data = malloc(XX * YY * ZZ * sizeof(double)); if (data == 0) { …allocation failed… } 以分配内存。其余使用数组的代码不需要改动一点。
  • 您可能会发现使用calloc() 而不是malloc() 以确保在使用前将内存清零是合适的。另请注意,即使您可以以 4 GHz 的速率将内存归零并设置每个时钟周期 8 个字节(64 位),仍然需要大约 30 秒才能将那么多内存归零。在那个阵列上没有什么会很快。

标签: c compilation relocation


【解决方案1】:
  • 这个 R_X86_64_PC32 是什么意思?

它是用于 x86_64 的 ELF 中的 ELF 重定位类型。这种特定类型表示引用数据的位置是根据与程序计数器相关的地址的 32 位偏移量计算的。我将诊断解释为表明所需的偏移量太大而无法容纳在提供的 32 位中,这意味着编译器生成的代码实际上链接器无法正确链接。

  • 我可以使用编译器标志来解决这个问题吗?

也许吧。基本问题是您定义的对象比编译器的作者(当时)想象的任何人都能够容纳的要大。你已经超出了它的设计限制。

可能有一些选项可以减轻这种影响。特别是,您可以尝试调整-fPIC 和/或-fPIE 选项,可能还有其他选项。

  • 有没有更好的方法来用 C 编写代码,同时又能保持编写代码的速度和简单性以提高可读性?

这不是 C 问题本身,这是一个实现问题。然而,就语言标准而言,GCC 在这里并没有错或有缺陷——该标准并没有强制实现接受所有在技术上有效的可能程序。

话虽如此,您也可以尝试将some_variable_thissome_variable_that 的声明移到data 的声明之后。可以想象,声明这些变量 static 或将它们(或 data)移动到单独的共享库也可能会有所帮助。

【讨论】:

  • 谢谢。我猜在这一点上,> 1TB 的共享内存服务器变得越来越可用,我在(数据段?)中简单地定义double myarray [HUGE]; 的旧方法不能再完成了。在 C 语言中,唯一可靠的方法是使用 malloc()calloc() ?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-13
  • 2016-06-30
  • 2011-08-29
  • 2013-12-25
  • 1970-01-01
  • 2018-04-06
相关资源
最近更新 更多