【问题标题】:Data types representing native signed and unsigned integer sizes?表示本机有符号和无符号整数大小的数据类型?
【发布时间】:2013-10-15 21:44:54
【问题描述】:

是否存在整数数据类型,在 16 位平台上始终为 2 个字节,在 32 位平台上为 4 个字节,在 64 位平台上为 8 个字节?假设 C++11,它将用于计算,而不是内存寻址。

有std::size_t,但什么是签名等价物(std::ptrdiff_t?),它是否保证满足要​​求?

有std::intptr_t和std::uintptr_t,但是they won't always be the same size as size_t

有std::int_leastN_t和std::int_fastN_t,但要么保证满足要​​求,如果满足,'N'的正确值是多少?

Boost 是否提供类似 a(n) int_native_t 和 uint_native_t 的东西?

【问题讨论】:

  • 这不就是int吗?
  • 取决于平台。 c++ 没有告诉你需要这种类型
  • 如果用于计算,不应该是应用程序定义整数的大小,而不是底层机器吗?
  • 不是真正的重复,但看看this
  • 更有趣的问题是,你为什么需要这样的东西?

标签: c++ boost c++11 embedded


【解决方案1】:

问题的问题在于,“16 位”或“32 位”之类的术语(通常源自本质上是 CPU 实现细节)如何转换为用户空间并不清楚。

例如,基于 Z80 的 8 位机器同时具有 8 位和 16 位寄存器和 16 位寻址内存,因此它们的 C 实现使int 16 位宽。 16 位机器(Amiga、Atari ST)有 32 位寄存器或使用段来寻址超过 64k 的内存(80286)。来自不同厂商的 Amiga C 编译器实现了不同宽度的int,并且没有被接受的“原生”int

重点不是你不能依靠intlong 告诉你架构的“大小”——这是你问题的前提——而是架构宽度实际上与一个C实现。在编写 C 代码时,您不应该关心总线的宽度,或者处理器内部一次抓取的位数。 (如果您真的需要关心这一点,那么您可能一开始就编写了不可移植的低级代码,并且从可移植类型声明中获益甚少。)

应该关心的是诸如您可以寻址的最大内存位置以及它是否适合整数类型、两个指针之差的大小或最大数组索引的大小, 等等。您可能还关心与系统接口的类型的宽度,例如您可以表示的纪元以来的最大时间段,或者您可以处理的文件的最大索引。您可以通过调整到标准 C 类型(例如 intptr_tptrdiff_tsize_ttime_toff_t 等)来获得所有这些 - 这就是它们的用途。

【讨论】:

  • 谢谢,您的回答有帮助。我了解到,我真正想要的可以由 (u)int_fast_##_t(u)int_least_##_t 数据类型表示,具体取决于我想要优化的内容。
【解决方案2】:

简短的回答是否定的。

最接近的可能是int,标准中说“......具有执行环境架构所建议的自然大小......”虽然这有点模糊并且基本上无法执行。例如,许多 64 位编译器仍然使用 32 位来表示 int

【讨论】:

    【解决方案3】:

    std::size_t 的签名等价物是 std::ssize_t

    【讨论】:

    • 真的是std::size_t。只是 size_t 不应该编译。
    • 当然。除非前面有using namespace std;
    • using namespace std; 不推荐。我认为有很多关于 SO 的帖子都说明了这一点。
    • 实际上,除非它是社区 wiki 帖子,否则编辑帖子以对 SO 进行此类更正是一种糟糕的形式。在评论中建议更改正是正确的地点。
    • ssize_t 不是标准 C++,它基于 POSIX 规范。 stackoverflow.com/a/15739797/711006
    【解决方案4】:

    如果它存在于您的<cstdint> 版本中,则uintN_t 形式的值(其中N 是位数)和intN_t 是精确宽度整数类型。不过,它们是可选的。

    【讨论】:

    • 我认为问题实际上是相反的——在 16 位平台上是否存在 16 位类型,在 32 位平台上是否存在 32 位类型等。 uintN_t 类型始终为 N 位宽,无论平台的
    【解决方案5】:

    你可以使用模板来实现一些东西:

    #include <cstdint>
    
    template<int size> struct native_ints;
    
    template<> struct native_ints<2> {
        using signed_int = std::int16_t;
        using unsigned_int = std::uint16_t;
    };
    
    template<> struct native_ints<4> {
        using signed_int = std::int32_t;
        using unsigned_int = std::uint32_t;
    };
    
    template<> struct native_ints<8> {
        using signed_int = std::int64_t;
        using unsigned_int = std::uint64_t;
    };
    
    using int_native_t = typename native_ints<sizeof(std::intptr_t)>::signed_int;
    using uint_native_t = typename native_ints<sizeof(std::intptr_t)>::unsigned_int;
    

    这依赖于intptr_t 具有本机机器整数的大小。

    【讨论】:

      【解决方案6】:

      根据this你可以做

      // Check windows
      #if _WIN32 || _WIN64
      #if _WIN64
      typedef uint64_t my_int;
      #else
      typedef uint32_t my_int;
      #endif
      #endif
      
      // Check GCC
      #if __GNUC__
      #if __x86_64__ || __ppc64__
      typedef uint64_t my_int;
      #else
      typedef uint32_t my_int;
      #endif
      #endif
      

      但这显然不是 16 位架构的解决方案。

      【讨论】:

        猜你喜欢
        • 2020-04-15
        • 2013-10-02
        • 2014-02-01
        • 2017-04-05
        • 2015-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多