size_t ptrdiff_t 和地址 space
size_t ptrdiff_t and address space
在我的系统上 ptrdiff_t
和 size_t
都是 64 位.
我想澄清两件事:
由于地址 space 的限制,我相信没有数组可以像 size_t
这样大。这是真的吗?
如果是,那么,是否可以保证ptrdiff_t
能够将任何指针的减法结果保持在最大范围内-大小的数组?
不,没有这样的保证。例如,参见此处:https://en.cppreference.com/w/cpp/types/ptrdiff_t
If an array is so large (greater than PTRDIFF_MAX elements, but less
than SIZE_MAX bytes), that the difference between two pointers may not
be representable as std::ptrdiff_t, the result of subtracting two such
pointers is undefined.
大多数实现人为地限制了最大数组大小,以确保指向同一数组的两个指针之间的差异适合 ptrdiff_t
。因此,在您的平台上,允许的最大数组大小很可能约为 SIZE_MAX / 2
(尝试一下)。这不是 "address space restriction",它只是您的实施在内部强制执行的限制。在此限制下,合法的指针减法("legal" = 两个指针指向同一个数组)不会溢出。
虽然语言规范没有要求。实现不需要以这种方式限制它们的数组大小,这意味着语言规范允许看似合法的指针减法溢出并产生未定义的行为。但是大多数实现更喜欢通过限制数组大小来防御这种情况。
请参阅此处的 "three options" 了解更多详情:
来自 [support.types.layout]/3
The type size_t
is an implementation-defined unsigned integer type that is large enough to contain the size in bytes of any object.
所以你保证 size_t
可以容纳你可以拥有的最大数组的大小。
ptrdiff_t
不幸的是不能保证。来自 [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 8.7.
还可以,但是我们有 [expr.add]/5
When two pointers to elements of the same array object are subtracted, the type of the result is an implementation-defined signed integral type; this type shall be the same type that is defined as std::ptrdiff_t in the header (21.2). If the expressions P and Q point to, respectively, elements x[i] and x[j] of the same array object x, the expression P - Q has the value i − j; otherwise, the behavior is undefined. [ Note: If the value i − j is not in the range of representable values of type std::ptrdiff_t, the behavior is undefined. —end note ]
其中指出 ptrdiff_t
可能不够大。
在我的系统上 ptrdiff_t
和 size_t
都是 64 位.
我想澄清两件事:
由于地址 space 的限制,我相信没有数组可以像
size_t
这样大。这是真的吗?如果是,那么,是否可以保证
ptrdiff_t
能够将任何指针的减法结果保持在最大范围内-大小的数组?
不,没有这样的保证。例如,参见此处:https://en.cppreference.com/w/cpp/types/ptrdiff_t
If an array is so large (greater than PTRDIFF_MAX elements, but less than SIZE_MAX bytes), that the difference between two pointers may not be representable as std::ptrdiff_t, the result of subtracting two such pointers is undefined.
大多数实现人为地限制了最大数组大小,以确保指向同一数组的两个指针之间的差异适合 ptrdiff_t
。因此,在您的平台上,允许的最大数组大小很可能约为 SIZE_MAX / 2
(尝试一下)。这不是 "address space restriction",它只是您的实施在内部强制执行的限制。在此限制下,合法的指针减法("legal" = 两个指针指向同一个数组)不会溢出。
虽然语言规范没有要求。实现不需要以这种方式限制它们的数组大小,这意味着语言规范允许看似合法的指针减法溢出并产生未定义的行为。但是大多数实现更喜欢通过限制数组大小来防御这种情况。
请参阅此处的 "three options" 了解更多详情:
来自 [support.types.layout]/3
The type
size_t
is an implementation-defined unsigned integer type that is large enough to contain the size in bytes of any object.
所以你保证 size_t
可以容纳你可以拥有的最大数组的大小。
ptrdiff_t
不幸的是不能保证。来自 [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 8.7.
还可以,但是我们有 [expr.add]/5
When two pointers to elements of the same array object are subtracted, the type of the result is an implementation-defined signed integral type; this type shall be the same type that is defined as std::ptrdiff_t in the header (21.2). If the expressions P and Q point to, respectively, elements x[i] and x[j] of the same array object x, the expression P - Q has the value i − j; otherwise, the behavior is undefined. [ Note: If the value i − j is not in the range of representable values of type std::ptrdiff_t, the behavior is undefined. —end note ]
其中指出 ptrdiff_t
可能不够大。