【问题标题】:Making 'long' 4 bytes in gcc on a 64-bit Linux machine在 64 位 Linux 机器上的 gcc 中制作“长”4 个字节
【发布时间】:2012-10-09 07:08:04
【问题描述】:

我正在将应用程序移植到 Linux 平台上的 64 位。该应用程序目前支持 Linux、Windows、Mac 32 位和 Windows 64 位。我们经常遇到的问题之一是将 long 用于 int,反之亦然。到目前为止,这不是问题,因为 long 和 int 在当前支持应用程序的平台中是可互换的(都是 4 个字节)。代码库是一个庞大的代码库,其中有许多带有#defines 的遗留代码用于许多数据类型,这使得搜索 long 的所有用法并用 int 适当地替换很麻烦。

  1. 作为短期解决方案,有没有办法让 GCC 使用 4 个字节而不是 8 个字节来表示“长”?
  2. 如果有,我们可能会面临哪些问题?如果没有,有没有更简单的方法来解决 long 和 int 问题?

【问题讨论】:

  • 这不是您当前问题的解决方案(因此是注释),但对于未来的代码,我会使用精确的宽度类型(例如,uint32_t)。

标签: linux gcc 64-bit long-integer


【解决方案1】:

-m32 生成 32 位代码。

-mx32 生成 64 位代码,但使用 32 位长整数和指针。

Intel 386 and AMD x86-64 Options

【讨论】:

  • 但是如何与使用 64 位长的系统库进行交互?
  • 原始发布者似乎需要 longs 为 32 位,因此他们需要链接到使用 32 位数据的库。我认为当一个函数被调用时,当它需要一个 32 位参数时,它不关心调用者的数据类型,也不关心调用者是否是 C 函数。但是是的,调用者必须确保不要调用需要 64 位值的库。
  • @johv:不会的。使用 -m32 您需要使用具有“常规”32 位 x86 ABI 的库,使用 -mx32 您需要使用 X32 库。
  • 所以您想生成 64 位代码,但您希望数据类型 long 为 32 位。然后一个非常丑陋的可能性是 -Dlong=int,它通常会起作用,但某些编码风格可能会阻止它。
  • @Windowsprogrammer: -Dlong=intlong int 转换为int int,这是一个语法错误。
【解决方案2】:
  1. 没有。在 Linux x86_64 上,ABI 指定 long 是 8 字节类型 (LP64)。事实上,如果不是全部的话,大多数 64 位 Unix 系统(包括 64 位 OS X、AFAIK)都是 LP64,所以这不是 Linux 特有的。

  2. 除了修复代码之外,没有。

如果您需要一个足够大的可移植整数类型来存储指针值,请使用 intptr_t 或 uintptr_t(但通常想要将指针值存储为整数意味着您做错了,所以请三思!) .对于能够表示两个指针之间差异的整数类型,请使用 ptrdiff_t。对于对象的大小,使用 size_t。

【讨论】:

  • 如果运行时库是静态链接的,ABI 不应该关心编译器调用“long”的类型,前提是任何外部库原型都是使用固定宽度类型和编译器定义的不会尝试使用具有相同表示但不匹配的类型的别名来做烦人的事情。
  • 这个答案显然是错误的(参见 WinProg 的那个)还是我错过了什么?
  • @janneb:这个答案表明 x86_64 上的 gcc 不可能为 long 使用 4 个字节。但是,是的,可以使用正确的标志,如另一个答案所示。
  • @calandoa:使用 -m32 或 -mx32 开关,编译器不会为 64 位 x86_64-pc-linux-gnu 目标生成代码,而是为 32 位 x86 目标生成代码( i686-pc-linux-gnu 以及 X32 的确切目标三元组是什么)。
  • @janneb:请参考doc“-mx32 选项将 int、long 和指针类型设置为 32 位,并为 x86-64 架构生成代码。” 。但我认为这个问题和你的答案存在混淆(就像我在 1000 万年前在我挖掘之前的情况一样):架构可以是 32 或 64,ABI 也可以是 32 或 64,所以我们最终得到32-32、64-32 和 64-64 组合。 [1/2]
【解决方案3】:

这取决于您所说的“移植到 64 位”是什么意思。

    1234563为此,您必须使用 32 位版本的 gcc(例如,Ubuntu 上的包 gcc:i386),或使用带有本机 gcc 版本的 -m32 标志。
  1. 您想从处理器的long mode 中受益(又名 x86_64 架构),但仍使用大多数 32 位 C 约定(包括 4 字节上的 long int):您可以使用 x32 ABI by使用 gcc 的 -mx32 标志,这要求您的发行版允许它(必须在您的内核中启用支持,并且需要特定的库,例如在 /libx32 中)。我使用的是 Ubuntu 16.04,这种模式运行得非常好,只是可用的预编译库要少得多。

  2. 您想完全使用 x86_64 架构和 ABI,但使用 4 个字节 long:这是不可能的,因为 x86_64 ABI 要求 long 为 8 个字节。

【讨论】:

    猜你喜欢
    • 2015-05-31
    • 2021-08-22
    • 2010-11-19
    • 2011-02-12
    • 2015-08-17
    • 2014-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多