繁体   English   中英

typedef 用于可以包含 size_t 的有符号类型?

[英]typedef for a signed type that can contain a size_t?

有符号类型的标准(或 MSVC 专有)typedef 可以包含全部size_t值吗? 即在 64 位系统上,它将是一个 128 位有符号整数。

一般来说,定义这样的类型是不可能的。 使size_t成为支持的最大无符号类型是完全合法的,这(几乎可以肯定)意味着没有有符号类型可以保存其所有值。

ptrdiff_t不一定足够宽。 这是两个指针相减的结果,但没有什么说指针减法不会溢出。 请参阅 C++ 标准的第 5.7 节:

当两个指向同一个数组对象的元素的指针相减时,结果就是两个数组元素的下标之差。 结果的类型是实现定义的有符号整数类型; 此类型应与<cstddef>标头 (18.2) 中定义为std::ptrdiff_t的类型相同。 与任何其他算术溢出一样,如果结果不适合提供的空间,则行为未定义。

最大的有符号类型是intmax_t ,在<stdint.h><cstdint>中定义。 这是 C99 的一个特性,C++11 是第一个包含 C99 标准库的 C++ 标准,所以你的编译器可能不支持它(MSVC 很可能不支持)。 9 年后:这不再是什么大问题了。 )如果有符号类型的宽度足以容纳size_t类型的所有可能值,那么intmax_t就是(尽管可能有更窄的有符号类型也符合条件)。

您还可以使用long long ,这是一种保证至少为 64 位的有符号类型(很可能与intmax_t相同)。 即使它的宽度不足以容纳size_t类型的所有可能值,它也几乎肯定会容纳size_t类型的所有相关值——除非您的实现实际上支持大于 8 EB(即 8192 PB 或 8388608 TB)的对象。

(注意,我使用的是“exa-”、“peta-”和“tera-”的二进制定义,它们的有效性值得怀疑。)

如果您想要一个可以包含系统最大值的标准类型,也许<cstdint> (C++11 起)会有所帮助。

该标头中有一个 typedef 包含最大宽度整数类型,类型为intmax_t 有符号整数的intmax_t和无符号整数的uintmax_t是体系结构完全支持的最大整数。

所以,让我们假设你在一个 64 位架构中,下面的指令:

std::cout << "intmax_t is same int64_t? "
          << (std::is_same<intmax_t, int64_t>::value ? "Yes" : "No");

将输出:

intmax_t 是否与 int64_t 相同? 是的

现场演示

希望能帮助到你。

我假设您需要这种类型来进行某种指针运算。 除了std::ptrdiff_t之外,您不太可能需要其他任何东西。 这将在现代机器上发挥作用的唯一情况是当您处于 32 位模式并且您正在处理超过 2^31 字节的数据集时。 (如果没有特殊工作,这甚至在 Windows 上都不可能。)您将无法同时使用两个该大小的数组。 在这种情况下,您可能无论如何都应该在 64 位模式下工作。

在 64 位模式下,以目前的内存发展速度,在未来 40 年左右的时间里,它很可能不会成为问题。 当它出现问题时,在 128 位模式下编译你的代码,它会继续运行。 ;)

如果您想要一个可以将std::size_t的每个值都保存为正值的有符号类型,我不知道有什么办法。 假设你有相同的位数,存储符号需要一位信息,所以新的最大值是旧的一半。 另一方面,使用该位的值的上半部分只是包装到负数中,因此您始终可以回退。

真的,您可能需要将高无符号/负符号值与其他值分开,无论您将它们投射到何处。 如果 unsigned 0 <= x < M/2 <= y <= M映射到0 <= (x, y & (M/2)) < M/2 ,那么每个值都被考虑在内,但不会包装为x 或 y 在任一方向。 如果有符号-M/2 <= y < 0 <= x < M/2映射到0 <= (x, y+M/2) < M则相同。

这样您就知道x < 0y > M/2何时超出转换范围,但同时您可以进行比较,例如 unsigned y(M) < y(M)+1或 signed x(0) > x(0)-1包装后通常会失败,例如0 < -1 = MM > M+1 = 0等。

作为记录,我认为最好计算std::size_t的相应签名类型std::make_signed_t<std::size_t> 目前它很可能是来自unsigned long long long long但我不知道它有多普遍,或者它是否会改变。 我建议从那里使用std::numeric_limits<T>来检查最小值/最大值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM