考虑以下代码:
int a[25][80];
a[0][1234] = 56;
int* p = &a[0][0];
p[1234] = 56;
第二行是否会调用未定义的行为?那么第四行呢?
两条线do导致未定义的行为。
下标被解释为指针加法后跟间接寻址,即a[0][1234]
/p[1234]
相当于*(a[0] + 1234)
/*(p + 1234)
。根据[expr.add]/4 http://eel.is/c++draft/expr.add#4(这里我引用的是最新的草案,而OP提出的时间,你可以参考这条评论 https://stackoverflow.com/questions/7269099/may-i-treat-a-2d-array-as-a-contiguous-1d-array#comment8749836_7269121,结论相同):
如果表达式P
指向具有 n 个元素的数组对象 x 的元素 x[i],表达式P + J
and J + P
(where J
如果 0≤i+j≤n,则值为 j) 指向(可能是假设的)元素 x[i+j];否则,行为是未定义的。
since a[0]
(衰减为指向a[0][0]
)/p
指向一个元素a[0]
(作为数组),以及a[0]
只有大小 80,行为未定义。
作为语言律师评论中指出 https://stackoverflow.com/questions/7269099/may-i-treat-a-2d-array-as-a-contiguous-1d-array#comment97470719_50795564,以下程序不编译 https://godbolt.org/z/Nfy1uE.
constexpr int f(const int (&a)[2][3])
{
auto p = &a[0][0];
return p[3];
}
int main()
{
constexpr int a[2][3] = { 1, 2, 3, 4, 5, 6, };
constexpr int i = f(a);
}
当它出现在常量表达式中时,编译器会检测到此类未定义的行为。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)