【发布时间】:2011-06-06 00:27:44
【问题描述】:
将此主题视为以下主题的续集:
让我们重温一下这个 funny 和 convoluted 表达式(斜体词组取自上述主题 *smile* ):
i += ++i;
我们说这调用了未定义的行为。我假设当这样说时,我们隐含地假设 i 的 type 是内置类型之一。
如果i 的type 是用户定义的类型怎么办?假设它的类型是Index,它在本文后面定义(见下文)。它还会调用 undefined-behavior 吗?
如果是,为什么?不等于写i.operator+=(i.operator++());,甚至语法上更简单的i.add(i.inc());?或者,它们是否也调用未定义行为?
如果没有,为什么不呢?毕竟,对象i 在连续序列点之间被修改两次。请记住经验法则:an expression can modify an object's value only once between consecutive "sequence points。如果i += ++i 是一个表达式,那么它必须调用未定义行为。如果是这样,那么它的等价物 i.operator+=(i.operator++()); 和 i.add(i.inc()); 也必须调用 undefined-behavior 这似乎是不真实的! (据我所知)
或者,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;
}
};
【问题讨论】:
-
+1 个很好的问题,激发了很好的答案。我觉得我应该说它仍然是可怕的代码,应该重构以提高可读性,但无论如何你可能都知道 :)
-
@什么是问题:谁说它是一样的?或者谁说不一样?它不取决于您如何实现它们吗? (注意:我假设
s的类型是用户定义的类型!) -
我没有看到任何 scalar 对象在两个序列点之间被修改两次...
-
@Johannes :那么它是关于 scalar 对象的。它是什么?我想知道为什么我以前从未听说过它。也许是因为教程/C++-faq 没有提到它,或者没有强调它?和内置类型的对象有区别吗?
-
@Phillip :显然,我不会在现实生活中编写这样的代码。事实上,没有理智的程序员会编写它。通常设计这些问题是为了让我们更好地理解未定义行为和序列点的整个业务! :-)
标签: c++ undefined-behavior c++-faq sequence-points