ptrdiff_t能否表示同一数组对象内指针的所有差值?——标准条款疑问
ptrdiff_t能否容纳同一数组元素指针间的所有差值?
这个问题问得特别到位,刚好触及了C++标准里看似矛盾的两个条款,咱们来把这层窗户纸捅破:
首先明确两个核心条款的含义:
- [support.types.layout#2]的强制要求:
ptrdiff_t是实现定义的有符号整数类型,必须能够容纳同一数组对象中任意两个下标之间的差值。换句话说,只要是标准合法的数组对象,不管它的规模多大(在实现允许的范围内),任意两个元素的下标差idx_a - idx_b,ptrdiff_t都能装得下——这是标准给实现方的硬性规定。 - [expr.add#5]的注释提醒:“若i−j的值不在std::ptrdiff_t的可表示值范围内,则行为未定义。” 这看起来和上面的规定冲突?其实不然,这个注释针对的是非法的指针减法操作:比如你拿两个完全无关的数组的指针相减,或者用数组末尾之后超过一个位置的指针来做减法——这类操作本身就已经是未定义行为了,而如果这种非法操作算出的差值刚好超出
ptrdiff_t的范围,那只是雪上加霜的另一种未定义场景。
关键结论
对于合法的同一数组对象的元素指针减法,标准已经通过[support.types.layout#2]的规定,保证了差值必然落在ptrdiff_t的可表示范围内,所以[expr.add#5]注释里的“超出范围导致未定义”的情况,根本不会发生在这种合规操作上。
举个实际的例子:假设某个实现中ptrdiff_t是64位有符号整数(最大值为2^63 - 1),那这个实现允许的最大数组大小必然不会超过2^63个元素——因为如果数组有2^63个元素,最后一个元素的下标是2^63 - 1,它和第一个元素的下标差就是2^63 - 1,刚好是ptrdiff_t的最大值;如果实现敢允许更大的数组,那就违反了[support.types.layout#2]的强制要求,属于不合格的实现。
内容的提问来源于stack exchange,提问作者jotik
相关产品推荐
相关产品推荐

