考虑本主题作为以下主题的续集:
前一篇文章
未定义行为和序列点
让我们重新审视这个 有趣 且 复杂 的表达式(斜体短语来自上述主题 *微笑*):
i += ++i;
我们说这会引发未定义行为。我认为当我们这样说时,我们隐含地假设i
的类型是内置类型之一。如果
i
的类型是用户定义的类型呢?比如它的类型是在本文稍后定义的Index
(见下文)。这是否仍会引发未定义行为?如果是,为什么?这不等同于写成
i.operator+=(i.operator++());
甚至更简单的语法i.add(i.inc());
吗?或者,它们也会产生未定义行为吗?如果不是,为什么?毕竟,在连续序列点之间,
i
对象被修改了两次。请记住经验法则:一个表达式只能在连续的“序列点”之间修改一次对象的值。如果i += ++i
是一个表达式,那么它必须引发未定义行为。如果是这样,那么它的等效表达式i.operator+=(i.operator++());
和i.add(i.inc());
也必须引发未定义行为,但这似乎是不正确的!(就我目前的理解而言)或者说,
i += ++i
本来就不是一个表达式?如果是这样,那它是什么,表达式的定义又是什么?如果它是一个表达式,同时其行为也是被定义的,那么这意味着一个表达式与它涉及的操作数的类型有关系,从而决定了与它相关的序列点个数。我的理解是否正确(即使只是部分正确)?
顺便问一句,这个表达式如何处理呢?
//Consider two cases:
//1. If a is an array of a built-in type
//2. If a is user-defined type which overloads the subscript operator!
a[++i] = i; //Taken from the previous topic. But here type of `i` is Index.
如果您确定它的行为,请在您的回答中考虑这一点。:-)
是
++++++i;
C++03中的定义是否良好?毕竟,这就是这个问题。
((i.operator++()).operator++()).operator++();
class Index
{
int state;
public:
Index(int s) : state(s) {}
Index& operator++()
{
state++;
return *this;
}
Index& operator+=(const Index & index)
{
state+= index.state;
return *this;
}
operator int()
{
return state;
}
Index & add(const Index & index)
{
state += index.state;
return *this;
}
Index & inc()
{
state++;
return *this;
}
};
s
的类型是用户定义的类型!) - Nawaz