重新审视未定义的行为和序列点
在主题“未定义的行为和序列点”的续集中,我们深入研究了涉及用户定义类型的表达式。
用户定义类型和未定义的行为
考虑以下涉及用户定义类型索引的表达式:
i += ++i;
此具有内置类型的表达式的行为未定义。但是,如果 i 是 Index 类型,它是否仍然会调用未定义的行为?
不,它不会。这是因为表达式等效于:
i.operator+=(i.operator++());
由于重载运算符是函数,因此应用正常的排序规则。 i.operator() 求值后存在序列点,因此后续 i.operator =() 中对 i 的修改不会违反任何未定义的行为规则。
同样,表达式 i.add(i .inc());和 i 定义明确。第一个表达式相当于:
i.operator+=(i.operator++());
第二个表达式相当于:
(i.operator++()).operator++()).operator++();
这些表达式中的每一个在运算符 () 表达式求值之后都有一个序列点,确保对象 i 在连续的序列点之间不会被修改两次。
下标运算符重载
表达式:
a[++i] = i;
其中a是重载下标运算符的用户定义类型,也是明确定义的。增量运算符返回一个 Index 对象,然后用它来索引 a 数组。赋值运算符=相当于operator[]()方法,它是一个函数调用。因此,排序规则适用,并且在评估 i 后存在序列点。因此,表达式是明确定义的。
附加点
以上是C 中的重载运算符是否可以消除'i = i”等表达式中的未定义行为?的详细内容。更多信息请关注PHP中文网其他相关文章!