18

新标准与旧标准具有不同的未定义行为。例如,新的排序规则意味着一些以前未定义的算术运算(由于序列点之间的多次写入等原因)现在被定义了。

那么,对于未定义的行为,我们需要重新学习什么?

4

2 回答 2

14

在我看来,新规则更难描述和理解。例如考虑:

int x = 12;
x = x++ + 1; // undefined behaviour
x = ++x + 1; // valid

我建议在同一个表达式中简单地避免对同一个变量的多个副作用,这是一个更容易理解的规则。AFAIK C++0X 改变了一些过去未定义行为而现在合法使用的情况(例如上面两个表达式中的第二个),但请记住,什么是合法的,什么是合法的是道德的;-) ...没有人强迫你使用这些东西。

实际上,在上述情况下,第二个表达式的有效性似乎是无意中发生的,这是解决语言中另一个问题(#222)的副作用。决定是使表达式有效,因为人们认为将某些内容从 UB 更改为明确定义不会造成任何伤害。然而,我认为虽然这并没有对程序造成任何损害(当然 UB 是最糟糕的问题),但它实际上对语言本身造成了一些损害......改变了一个已经很难解释和理解的规则一个更晦涩的。

IMO C++ 正在继续从 C 语言自然演变成一种语言,在这种语言中,一堆好看、漂亮、合乎逻辑的语句可以做很棒的事情……而另外一堆同样好看、同样漂亮和同样合乎逻辑的语句可以让你的电脑爆炸反而。

于 2010-12-07T17:42:20.747 回答
3

C++0x 将许多以前未定义的情况更改为现在有条件支持的情况。语义是:

  • 如果实现不支持有条件支持的特性,它应记录该特性并为违反它的程序发出诊断。
  • 如果实现确实支持它,它应该符合标准对其提出的附加要求。例如,标准可能会说某些东西是由实现定义的语义有条件地支持的。如果是这样,实现应记录它如何支持该功能。

以前未定义的一种流行情况是,当通过省略号函数参数传递具有非平凡复制构造函数、非平凡移动构造函数或非平凡析构函数的类类型参数时。现在这是有条件的支持,具有实现定义的语义。

于 2010-12-12T01:00:35.720 回答