jot*_*tik 32 c++ arrays pointer-arithmetic language-lawyer ptrdiff-t
对于指针的减法i和j同一数组对象的元素,[expr.add#5]中的注释读取:
[ 注意:如果值i-j不在类型的可表示值范围内
std?::?ptrdiff_t,则行为未定义.- 结束说明 ]
但是给出[support.types.layout#2],其中指出(强调我的):
- 该类型
ptrdiff_t是一个实现定义的有符号整数类型,它可以保存数组对象中两个下标的差异,如[expr.add]中所述.
结果是否可能i-j不在可表示的值的范围内ptrdiff_t?
PS:如果我的问题是由于我对英语的理解不足造成的,我道歉.
编辑:相关:为什么数组的最大大小"太大"?
结果是否可能
i-j不在可表示的值的范围内ptrdiff_t?
是的,但不太可能.
事实上,[support.types.layout]/2并没有说话,除了指点一下减法适当的规则和ptrdiff_t中定义[expr.add].那么让我们看看这一节.
[expr.add]/5当减去指向同一数组对象的元素的两个指针时,结果的类型是实现定义的有符号整数类型; 此类型应
std?::?ptrdiff_t与<cstddef>标题中定义的类型相同.
首先,请注意,这里的情况i和j不同的阵列的标指标不考虑.这允许以治疗i-j为P-Q将是其中P是一个指针阵列中的下标元素i和Q是指向的元件相同的在标数组j.实际上,减去两个指向不同数组元素的指针是未定义的行为:
[expr.add]/5如果表达式
P和Q指向,分别,元件x[i]和x[j]同一阵列对象的x,表达P - Q具有值i?j; 否则,行为未定义.
作为结论,使用先前定义的符号,i-j并且P-Q被定义为具有相同的值,后者是类型std::ptrdiff_t.但没有人说这种类型存在这种价值的可能性.但是,可以在以下帮助下回答这个问题std::numeric_limits; 特别是,可以检测数组some_array是否太大而std::ptrdiff_t无法容纳所有索引差异:
static_assert(std::numeric_limits<std::ptrdiff_t>::max() > sizeof(some_array)/sizeof(some_array[0]),
"some_array is too big, subtracting its first and one-past-the-end element indexes "
"or pointers would lead to undefined behavior as per [expr.add]/5."
);
Run Code Online (Sandbox Code Playgroud)
现在,在通常的目标上,这通常不会发生sizeof(std::ptrdiff_t) == sizeof(void*); 这意味着一个数组需要很大ptrdiff_t才能溢出.但不能保证.
| 归档时间: |
|
| 查看次数: |
569 次 |
| 最近记录: |