size_t 是否与 ptrdiff_t 具有相同的大小和对齐方式?

Does size_t have the same size and alignment as ptrdiff_t?

在我的平台上(我认为在大多数平台上)std::size_tstd::ptrdiff_t 具有相同的大小和相同的对齐方式。有什么平台不是这样的吗?简而言之:标准要求吗?

In short: is it required by the standard?

没有。唯一的要求来自 [support.types.layout]/2,它是:

The type ptrdiff_­t is an implementation-defined signed integer type that can hold the difference of two subscripts in an array object, as described in [expr.add].

paragraph 4

[ Note: It is recommended that implementations choose types for ptrdiff_­t and size_­t whose integer conversion ranks are no greater than that of signed long int unless a larger size is necessary to contain all the possible values. — end note ]

但是注释是非规范的,只是建议,不是要求。


std::size_t 定义为

The type size_­t is an implementation-defined unsigned integer type that is large enough to contain the size in bytes of any object ([expr.sizeof]).

paragraph 3 中,也没有要求它们相同。

标准没有要求。

请注意,当前的 Intel 处理器内部有 48 位指针。

所以我个人认为为 std::size_t 构思 64 位 unsigned 和为 std::ptrdiff_t 构思 49 位签名类型并不太牵强。虽然这样的方案实施起来会很头疼。

更有趣的是,一旦芯片组发展到具有 64 位指针(我们离实现这一点还有一段距离),大概 std::ptrdiff_t 必须至少是 65 位!因此,我个人记住,有一天 sizeof(std::ptrdiff_t) 可能会大于 sizeof(std::size_t)

On my platform ... std::size_t and std::ptrdiff_t have the same size

这是否合规?

C 有(我相信 C++ 继承 - 如果不让我知道删除)作为§ J.2 中的 UB:

The result of subtracting two pointers is not representable in an object of type 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可能在数组元素计数[=31=时开始] ] 超过 PTRDIFF_MAX.