是否有一个整数数据类型,在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的内容?
答案 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
。
关键不在于您不能依靠int
或long
来告诉您架构的“大小” - 这是您的问题的前提 - 但架构宽度是实际上与C实现无关。编写C代码时,您不应该关心总线的宽度,也不应该关心处理器内部一次抓取的位数。 (如果你真的需要关心它,你可能会开始编写不可移植的低级代码,并且从便携式类型声明中获得的好处很少。)
你应该关心的是你可以解决的最大内存位置以及它是否适合整数类型,两个指针的差异大小或最大数组索引的大小, 等等。您可能还关心与系统接口的类型的宽度,例如您可以表示的纪元以来的最大时间段,或者您可以解决的文件中的最大索引。您可以通过调整标准C类型来获得所有这些,例如intptr_t
,ptrdiff_t
,size_t
,time_t
,off_t
和其他类型 - 这就是他们是为了。
答案 1 :(得分:4)
简短的回答是否定的。
最接近的可能是int
标准所说的“......具有执行环境架构所建议的自然大小......”这有点模糊,但基本上无法执行。例如,许多64位编译器仍然使用32位int
。
答案 2 :(得分:1)
已签名的等效std::size_t
为std::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位架构的解决方案。