【问题标题】:unsigned long long vs unsigned long(portability point of view)unsigned long long vs unsigned long(可移植性的观点)
【发布时间】:2012-05-24 18:52:48
【问题描述】:

我希望能够在我的项目中使用大的正整数(8 字节),即使 sizeof(unsigned long) 在我的系统中产生 8,我读到在大多数系统中 unsigned long 只有 4 字节,我决定试试 unsigned long long,因为它保证至少有 8 个字节。

虽然我使用它的次数越多,我发现它也不是超级便携,例如在某些系统中(取决于编译器)printf 使用 %llu 格式化它,在某些系统中它使用 %lld 格式化它。

我的代码只能在 64 位 debian 机器上运行,其中 unsigned long 将是 8 个字节。便携性不是一个大问题。在这种情况下使用 unsigned long long 而不是 unsigned long 是不是有点过头了,使用 unsigned long long 而不是 unsigned long 还有其他好处吗?

【问题讨论】:

  • 你试过uint64_t吗?它在<stdint.h>.
  • 使用它比 unsigned long long 有什么优势?
  • 如果你没有任何类型正好是 64 位,而 long long 沿着更长的类型,它会停止编译。两者都存在于 C++11 中,两者都经常作为扩展存在,但如果有时存在一个而不存在另一个,我不会感到惊讶。如果你没有它,stdint.h 比 long long 更容易模拟(假设类型存在)。
  • 谢谢,我会考虑使用的。
  • 一个相关问题here.

标签: c++ unsigned-long-long-int


【解决方案1】:

unsigned long long 保证至少为 64 位,无论平台如何。 (有些平台更多——我知道 72 位和 96 位——但它们很少见,而且绝对是异国情调。)unsigned long 保证至少是 32 位。如果您需要超过 32 位,我会推荐 unsigned long long

关于格式,printf,你应该使用"%llu"(因为它是无符号的); "%lld" 代表signed long long

【讨论】:

  • 感谢 James,我也是这么想的,使用 unsigned long long 肯定更安全。不过,这里有个问题,因为在我的开发和目标环境中 unsigned long 是 8 个字节,我可以改用 unsigned long 吗?顺便说一句,当我将 %llu 与 unsigned long long 一起使用时,编译器会发出警告,这些不可移植性让我不敢使用 unsigned long long。
  • “至少 64 位”保证不是只有 C++11 以后才有的吗?
  • @erinc 如果您在long longlong 大小相同的平台上工作,则生成的代码应该相同,因此没有理由不使用@987654330 @。如果编译器在将unsigned long long 传递给"%llu" 时发出警告,则只能将其视为错误。传递给"%llu" 的唯一合法类型是unsigned long long;传递任何其他类型都是未定义的行为。
  • @juanchopanza 在 C++11 之前,C++ 没有 long long。然而,C90 做到了,并且要求它至少为 64 位。微软使用__int64 有一段时间(考虑到long long 是一个Unixism,直到C90 正式发布),但现在已经支持long long 很长时间了。甚至在 C90 之前,long long 起源的 Unix 平台都要求它至少为 64 位。
  • 再次感谢,我使用的是 gcc v 4.3.2,看起来它已经支持很长时间了。好的,在这种情况下,我将继续使用 unsigned long long。
【解决方案2】:

如果你想留下来很长很长,你可以这样做:

#include <limits.h>
#if ULONG_MAX >= 0xFFFFFFFFFFFFFFFFULL
typedef unsigned long uint64;
#else
typedef unsigned long long uint64;
#endif

W.r.t.这个

在某些系统中(取决于编译器)printf 使用 %llu 对其进行格式化,在某些系统中使用 %lld 对其进行格式化

printf() 不猜测格式。你告诉它格式。

如果你想打印上面定义的uint64,这样做:

printf("%llu", (unsigned long long)some_uint64_value);

您可以typedef unsigned long long ulonglong; 使演员更容易打字。

确实存在其他方法可以做到这一点,但并非所有编译器都支持它们。这就是为什么我在号码后面加上ULL 后缀。在 C89 和 C99 之间的某些兼容模式中,0xFFFFFFFFFFFFFFFF 可能被解释为unsigned long,而不是unsigned long long,并将被截断。最新的 gcc 默认以 gnu89 模式运行 C 代码,而不是 c99 或更高版本。

【讨论】:

    【解决方案3】:

    如果您需要确保具有固定大小的整数值,独立于平台,您可以使用 boost::integers 库(请参阅here)。您可以将 boost::int64_t 或 boost::uint64_t 用于无符号值

    【讨论】:

    • 为什么使用 boost 而不是 stdint.h uint64_t?
    猜你喜欢
    • 2016-07-29
    • 2015-08-22
    • 1970-01-01
    • 1970-01-01
    • 2015-01-30
    • 1970-01-01
    • 2012-01-27
    • 1970-01-01
    • 2016-12-20
    相关资源
    最近更新 更多