我应该在可移植代码中使用long long还是int64_t?

45

我有一个开源代码库,用 C 和 C++ 编写。我正在寻找一种至少保证宽度为 64 位的整数类型,可以在大多数 OS X(Intel,64 位)和 Linux 系统的开源 C 和 C++ 编译器上可靠地编译,而不需要用户做太多额外的工作。目前不需要支持 Windows 和 32 位客户端。

我在 OS X 上进行了一些测试,最新的 developer tools 自带的 GCC 不支持 C+11 模式(因此似乎不能保证 long long 可用)。Clang 也不支持这个模式,尽管在某个版本之后启用 C99 模式可以支持 long long

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

我能否可靠地将 int64_t 强制转换为 long long(以及使用带有 unsigneduint64_t 的等效方式),以便将其与现有函数和库一起用于接受 long long 作为参数的情况?(当然必须还原回去。)

在这种情况下,如果我发布需要 Clang 功能而 GCC 不支持的代码,那么 Clang 是否会取代 GCC 成为 Linux 的首选编译器?当提供源代码给终端用户时,我是否可以大多数情况下期望使用这个编译器?

基本上,我想向其他开发人员请教一些建议,他们已经在可移植 C 和 C++ 代码中使用了这两种类型,并可能对考虑以上目标时哪种方式更好有一些建议。


在C++11之前,gcc已经将long long作为扩展功能。只要您不禁用gcc扩展,使用long long应该没有问题(实际上,我认为我很长时间以来都没有使用/看到过不提供long long的编译器)。 - Grizzly
请注意,int64_t 可以具有底层类型 longlong long 等,如果需要重载可能会导致可移植性问题。 - Mark B
还要考虑使用typedef,以便在不同平台之间轻松进行更改。 - geometrian
1
需要考虑的一件事是,使用int64_t的重载或模板可能会在不同的系统上选择不同的版本。请参见int64_t vs long vs long long上的另一个问题。 - Bo Persson
3个回答

34

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


我希望标准能够增加一个更大的类型,比如128或更大。考虑到现在加密技术被广泛应用,我们需要这样一种类型,这样就不必依赖于很多库了。 - farmdve
我还没有看到过这种类型(long long long?)的提案,尽管我知道许多系统实际上通过SIMD支持来支持128位类型:向WG14和/或WG21提交一个提案吧! - Dietmar Kühl
2
“long long long” 不是必需的;支持 128 位整数的系统可以定义扩展整数类型,并根据这些类型定义 int128_tuint128_t - Keith Thompson
2
如果OP想要至少64位的最快类型,那么int_fast64_tuint_fast64_t会更好。 - phuclv

31

当追求可移植性时,是否一般建议使用int64_t代替long long

如果编译器支持long long,那么使用int64_t会令人惊讶。

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

如果需要一个精确64位的类型,使用(u)int64_t,如果需要至少64位,则(unsigned) long long完全可以,(u)int_least64_t也可以。


0

使用int64_t。 int64_t表示64位,您将在任何地方得到64位。 long long实际上像long一样取决于实现。也就是说,long long必须比long大或相等,但这取决于编译器和平台。


标准中保证了long long至少为64位。它可能更长,但不能更短。因此,不,它不像long那样依赖于实现:对于long,规则是它只需要和int一样长,而int只需要比char大。因此,你可以有一个平台,其中sizeof(long)==2,但在每个平台上,sizeof(long long)>=8必须为真。 - cmaster - reinstate monica
谢谢。知道这一点很好。但至少 sizeof(long long) 仍然取决于平台,想要获得一致的 64 位,唯一的方法是使用 int64_t。 - TJ Bandrowsky
是的,但问题是关于“至少为64位宽度的整数类型”。这正是long long所提供的。 - cmaster - reinstate monica
OP谈论的是可移植性,因此我会选择固定大小:int64_t。它指的是64位,所以你甚至不必考虑它。 - TJ Bandrowsky
“long long”是可移植的,因为它是标准的一部分。如果您没有“long long”,那么您极有可能也没有“int64_t”。 - cmaster - reinstate monica
多年来,微软没有提供long long类型,而是使用本地的__int64来获取64位,并有时甚至定义__int64_t。不确定他们什么时候开始支持long long。 - TJ Bandrowsky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接