【问题标题】:Should I use long long or int64_t for portable code?对于可移植代码,我应该使用 long long 还是 int64_t?
【发布时间】:2012-09-10 04:50:41
【问题描述】:

我有一个用 C 和 C++ 编写的开源代码库。我正在寻找一种保证 至少 64 位宽的整数类型,它可以在大多数 OS X(英特尔,64 位)和具有开源 C 的 Linux 机器上可靠地编译和 C++ 编译器,最终用户无需做太多额外的工作。 Windows 和 32 位客户端支持目前并不重要。

我在 OS X 上做了一些测试,开发者工具附带的最新 GCC 不支持 C+11 模式(因此似乎不能保证long long 的可用性)。 Clang 也不支持这个,虽然它支持 long long 如果启用 C99 模式,在某个版本之后。

当可移植性是一个重要目标时,一般建议是否使用int64_t 代替long long?使用格式说明符似乎很痛苦。

我能否可靠地将int64_t 转换为long long(以及与uint64_t 等效的unsigned)以将其与以long long 作为参数的现有函数和库一起使用? (当然又回来了。)

在这种情况下,如果我发布的代码需要 Clang 功能而不是 GCC,那么 Clang 会取代 GCC 作为 Linux 上的首选编译器吗?在向最终用户提供源代码时,大部分情况下我可以期待那个编译器吗?

基本上,我想向其他使用这两种类型的可移植 C 和 C++ 代码的开发人员征求一些建议,考虑到上述情况,他们可能会对什么可能是更好的长期发展方式提出一些建议牢记目标。

【问题讨论】:

  • gcc 在 c++11 之前有 long long 作为扩展,所以只要你不禁用 gcc-extensions 你应该可以在 gcc 上使用 long long (其实我不'认为我已经使用/看到过长时间不提供 long long 的编译器)。
  • 请注意,int64_t 可以具有基础类型 longlong long 等,如果需要重载,可能会导致可移植性问题。
  • 还可以考虑使用 typedef 来轻松地在平台之间进行更改。
  • 需要考虑的一点是,使用 int64_t 的重载或模板可能会在不同的系统上选择不同的版本。见this other question on int64_t vs long vs long long

标签: c++ c types int64 long-long


【解决方案1】:

使用 int64_t。 int64_t 表示 64 位,无论您走到哪里,都会得到 64 位。 long long 实际上与 long 一样依赖于实现。也就是说,long long 必须大于或等于 long,但这可能因编译器和平台而异。

【讨论】:

  • 标准中保证long long 必须至少为64 位。它可能更长,但它不能更短。所以,不,它不像long 那样依赖于实现:对于long,规则是,它只需要与int 一样长,它只需要大于char。因此,您可以拥有一个带有sizeof(long) == 2 的平台,但sizeof(long long) >= 8 在每个平台上都必须为真。
  • 谢谢。很高兴知道。但至少 sizeof(long long) 仍然取决于平台,获得一致 64 位的唯一方法是 int64_t。
  • 是的,但问题是关于“保证至少 64位宽的整数类型”。这正是long long 所提供的。
  • OP 说的是可移植的,所以我会选择固定大小:int64_t。它说的是 64 位,所以你甚至不必考虑它。
  • long long 作为标准的一部分是可移植的。如果你没有long long,你也很可能没有int64_t
【解决方案2】:

long longunsigned long long 类型是标准 C 和标准 C++ 类型,每个类型至少有 64 位。我知道的所有编译器都提供这些类型,除非可能在 -pedantic 模式下,但在这种情况下,int64_tuint64_t 也不适用于 C++ 2011 之前的编译器。在所有系统上<stdint.h> 也可用。也就是说,据我所知,你如何拼写类型并不重要。 <stdint.h> 的主要目标是为特定位数提供最佳匹配。如果您需要至少 64 位,但又想利用这种类型的快速实现,您可以使用 int_least64_tuint_least64_t 来自 <stdint.h><cstdint> (在后者的情况下,名称在命名空间 std 中定义。

【讨论】:

  • 我肯定希望标准添加更大的类型,例如 128 或更大,考虑到在密码学被大量使用的今天,您需要这样的类型,因此您不必依赖在许多图书馆。
  • 我还没有看到关于这种类型的提案 (long long long?) 虽然我知道许多系统实际上通过 SIMD 支持支持 128 位类型:向 WG14 发送提案并/或WG21!
  • long long long 不是必需的;支持 128 位整数的系统可以定义扩展整数类型,并根据这些类型定义int128_tuint128_t
  • 如果 OP 想要最快的类型,至少 64 位,int_fast64_tuint_fast64_t 会更好
【解决方案3】:

当可移植性是一个重要目标时,一般建议是否使用int64_t 代替long long

如果编译器提供int64_t 而不是long long,我会感到非常惊讶。

如果 long long 存在,它必须至少有 64 位,因此从 (u)int64_t 转换为 (unsigned) long long 是保值的。

如果您需要正好 64 位的类型,请使用(u)int64_t,如果您需要至少 64 位,(unsigned) long long 完全可以,就像这样(u)int_least64_t.

【讨论】:

    猜你喜欢
    • 2012-12-11
    • 2012-05-24
    • 2011-05-08
    • 1970-01-01
    • 2022-12-15
    • 1970-01-01
    • 1970-01-01
    • 2016-12-16
    • 1970-01-01
    相关资源
    最近更新 更多