未定义的行为和序列点:深入探讨
表达式 i = i;已被标记为调用未定义行为 (UB),但是如果 i 的类型是用户定义的(如提供的 Index 类中所示)怎么办?
用户定义类型和 UB
对于像 Index 这样的用户定义类型,表达式 i = i;仍算UB。这是因为用户定义类型不会覆盖增量运算符的默认行为。 operator()和operator =()函数仅修改Index对象的内部状态,并不创建任何序列点。因此,表达式在连续序列点之间修改对象两次,从而产生 UB。
表达式的等价
表达式 i.operator =(i.operator () );和 i.add(i.inc());不等于原来的 i = i;。在第一个表达式中,i.operator () 求值之后的序列点允许在 = 运算符求值之前修改 Index 对象。类似地,在第二个表达式中,成员函数 add 和 inc 不会修改连续序列点之间的对象。因此,这些表达式不会调用 UB。
表达式定义和序列点
表达式 i = i;确实是一个表达式,但其行为没有明确定义。与表达式关联的序列点的数量不取决于所涉及的操作数的类型。
数组下标 (a[ i] = i)
表达式 a [我]=我;当 a 是内置类型的数组或 a 是重载下标运算符的用户定义类型时,在这两种情况下也为 UB。在这两种情况下,首先计算 [ i] 表达式,它递增 i 并返回其递增前的值。然后将该值用作数组的索引,如果索引越界,可能会导致 UB。
多次递增操作 ( i)
表达式一;在 C 03 中定义良好,并且与表达式 ((((i.operator ()).operator ()).operator ()).operator ()).operator ()); 具有相同的行为。每个operator()调用都会返回对Index对象的引用,并且每个函数求值后的序列点确保该对象在连续的序列点之间仅被修改一次。
结论
总之,表达式 i = i;且a[i]=i;为用户定义的类型调用 UB,即使这些类型提供重载运算符。 Index 对象上的多个增量操作是明确定义的,这表明序列点和序列点之间对象的修改次数与所涉及的操作数类型无关。
以上是即使对于用户定义的类型,'i = i;”也是未定义的行为吗?的详细内容。更多信息请关注PHP中文网其他相关文章!