遗留系统中的一个问题已经简化为代码,它对自身执行“自动”数组索引,如下所示:
int x[4] = {1,2,3,4};
std::cout << x[++*+x] << " " << x[*+x+1] << "\n";
代码从未经历过可读性和可维护性的代码审查,我试图理解为什么它输出 3 和 4 ?我不清楚它是如何索引到数组中的。
答案 0 :(得分:3)
代码会对数组进行索引,但它也会更改数组。它相当于,
std::cout << x[++x[0]] << " "; // the array becomes {2,2,3,4}
std::cout << x[x[0]+1] << "\n";
请注意,+x
只是数组的指针地址。标准的相关部分在5.3.1 [expr.unary.op]
中说明:
一元+运算符的操作数应具有算术,无范围枚举或指针类型和 结果是参数的值。
答案 1 :(得分:0)
建立在模拟接口的答案上。 (我的评论太大了,不适合评论!)
代码更清楚地表达为:
std::cout << x[++x[0]] << " " << x[x[0]+1] << "\n";
但是,在C ++ 98和C ++ 03 中会导致未定义的行为。
向右阅读x[0]
,x[0]
的增量可以
在没有插入序列点的情况下发生。 (即使这些
operator调用是函数调用,所有参数都可以
在调用任何函数之前进行评估。)
(C ++ 11改变了排序规则,IDK是否为此代码 现在定义明确,或者如果是这样,哪些操作首先发生。)
此外,只有表达式x[++x[0]]
会导致未定义的行为
事先x[0] == -1
,因为之间没有序列点
增量和x[0]
的外部访问权限。
我建议用不能表达的东西替换这个表达式 混合增量和读数。例如:
int index = ++x[0];
if ( index >= 0 && index < (int)lengthof(x) - 1 )
std::cout << x[index] << " " << x[index+1] << "\n";
else
std::cout << "index out of bounds on x[]\n";