要在可移植C++库中使用的整数类型



我维护着一个开源库,该库应该在多个平台上运行,并提供(以及其他)本机数据类型的数学例程。我们希望尽可能提供 64 位计算。

我们的目标平台是32位和64位的Linux和OSX,Windows尚不受支持,但已知大多数代码都可以在Windows下运行,因此我们可以在不远的将来轻松移植到Windows。因此,至于 http://en.cppreference.com/w/cpp/language/types,我们对ILP32,LLP64和LP64感兴趣。我们还与 gmp 交互(gmp 只提供 intlong 的构造函数,但不提供 long long 的构造函数)。

我们现在遇到了问题,这些问题归结为我们使用哪些本机整数类型作为数字类型的默认值:

  • 如果我们使用 int ,我们在 32 位平台上回退到 64 位。
  • 如果我们使用 long ,我们在 Linux/OSX 64 与 Windows 64 之间有不一致的行为:Windows 将无法采用 64 位计算。
  • 如果我们使用 long long ,使用 gmp 会变得一团糟,因为从long long创建mpz_class会导致模棱两可的重载。我们必须事先将数字转换为长整型(因此在许多地方有效地在Windows上仅使用32位。
  • 如果我们使用 std::int64_t 和类似,则不同平台之间的 typedef 不同,因此我们会遇到相同的问题,只是每个平台的问题不同......

有没有某种最佳实践?是否有可能避免这些问题,或者它们是C++型系统固有的?

当然,问题还不止于此。需要考虑的其他未决问题:

  • 这些解决方案中的每一个如何与例如std::size_t交互? std::size_t有它的目的,但有时它需要与我们计算的数字相互作用。显然,我们不想一直来回投掷。
  • 我们如何处理其他数字类型的用法?如果我们提供一个f(T)的功能并为T = int,long,long long提供重载,但用户使用它与std::int64_t,我们是否可以避免不同平台之间的不一致行为?(对std::int64_t有不同的定义)如果我们还为 std::int64_t 提供重载,我们将有重复的重载。

PS:我已经阅读了c-long-long-int-vs-long-int-vs-int64-t和应该使用long-long-long-or-int64-t-for-portable-code。我在那里得到了一些了解,到底发生了什么以及为什么会这样,但无法得出解决方案......

根据定义,Windows 上的 gmp 似乎永远不会支持 64 位值。所以我建议在你的代码中使用int64_t,任何时候你需要先与gmp交互,static_castlong

最新更新