【发布时间】:2020-09-08 03:56:15
【问题描述】:
在我的平台上(我认为在大多数平台上)std::size_t 和 std::ptrdiff_t 具有相同的大小和相同的对齐方式。有没有不正确的平台?简而言之:是标准要求的吗?
【问题讨论】:
标签: c++ language-lawyer size-t ptrdiff-t
在我的平台上(我认为在大多数平台上)std::size_t 和 std::ptrdiff_t 具有相同的大小和相同的对齐方式。有没有不正确的平台?简而言之:是标准要求的吗?
【问题讨论】:
标签: c++ language-lawyer size-t ptrdiff-t
简而言之:是标准要求的吗?
没有。唯一的要求来自[support.types.layout]/2,它是:
ptrdiff_t 类型是实现定义的有符号整数类型,可以保存数组对象中两个下标的差异,如 [expr.add] 中所述。
[ 注意:建议实现为 ptrdiff_t 和 size_t 选择整数转换等级不大于signed long int 的类型,除非需要更大的大小来包含所有可能的值。 ——尾注]
但注释是非规范性的,它只是一个建议,而不是要求。
std::size_t 定义为
类型 size_t 是实现定义的无符号整数类型,它大到足以包含任何对象 ([expr.sizeof]) 的大小(以字节为单位)。
在paragraph 3中,也没有要求必须相同。
【讨论】:
size_t 的要求,它紧跟在您为ptrdiff_t 链接的要求之后。
ptrdiff_t 不是size_t 的签名版本在哪个平台上?
size_t 自然是 16 位,但您希望 ptrdiff_t 更大,以便您可以拥有大小在 32K 和 64K 之间的 char 数组。事实上,en.cppreference.com/w/cpp/types/ptrdiff_t 有一条注释,C++11 要求 ptrdiff_t 至少为 17 位宽。
标准没有要求。
请注意,当前的英特尔处理器具有 48 位指针。
所以我个人认为,为std::size_t 设计一个 64 位 unsigned 并为std::ptrdiff_t 设计一个 49 位有符号类型并不太牵强。虽然这样的方案实施起来会很头疼。
更有趣的是,一旦芯片组发展为具有 64 位指针(我们离必要的还有一段距离),大概std::ptrdiff_t 将必须至少为 65 位!因此,我个人记住,sizeof(std::ptrdiff_t) 可能大于sizeof(std::size_t)。
【讨论】:
xor 是当时许多复制保护/代码加密的基础,尤其是对于未记录的 R 寄存器,您不能只在调试器中单步执行来解密代码。那时我可能玩过巫术!真正的高性能代码使用push 在屏幕上绘图,因为它是存储单词并移动到上一个写入位置的最快方式。
在我的平台上...
std::size_t和std::ptrdiff_t大小相同
这如何合规?
C 有(我相信 C++ 继承了 - 如果不让我知道删除)作为 § J.2 中的 UB:
两个指针相减的结果无法在
ptrdiff_t(6.5.6) 类型的对象中表示。"
这允许ptrdiff_t 的类型成为未签名size_t 的签名对应项。
当这样配对没有填充时,
char a[PTRDIFF_MAX + (size_t)1]; // OK with enough memory in the location needed
size_t size_a = sizeof a; // OK
size_t diff0 = &a[sizeof a - 1] - &a[0]; // OK
ptrdiff_t diff1 = &a[sizeof a] - &a[0]; // UB
ptrdiff_t diff2 = %a[0] - &a[sizeof a]; // UB
故事的寓意:指针减法的麻烦(结果类型:ptrdiff_t)可能在数组元素计数超过PTRDIFF_MAX时开始。
【讨论】: