表示本机有符号和无符号整数大小的数据类型?

时间:2013-10-15 21:44:54

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

是否有一个整数数据类型,在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是否提供类似(n)int_native_t和uint_native_t的内容?

6 个答案:

答案 0 :(得分:7)

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

例如,基于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和其他类型 - 这就是他们是为了。

答案 1 :(得分:4)

简短的回答是否定的。

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

答案 2 :(得分:1)

已签名的等效std::size_tstd::ssize_t

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

#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具有本机整数的大小。

答案 5 :(得分:-1)

根据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位架构的解决方案。