序列点来自哪里?

我知道写点东西

++a = a++; 

不仅不可读而且违反了c / c ++序列点。

这些限制来自哪里? 在将它们发现为错误之前,如何才能看到这些“问题”?

基本上每个语句之间都有一个C ++ 03序列点。 有关更多信息,请参阅SO C ++ FAQ 。 有关更多信息,请参阅C ++标准,并记住在C ++ 11标准中,序列点被替换为之前的 序列和关系之后的序列

为避免出现问题,请不要试图在每个表达式中做很多事情。

不要尝试编译器的工作:将其留给编译器。 您的工作是编写其他人可以轻松理解的代码 ,即清晰的代码 。 多次更新和不必要地使用具有副作用的操作员与此不兼容。

提示:尽可能在任何地方撒上const

这限制了读者必须考虑的可能的状态变化。

它们来自C或C ++标准,它有效地列出了序列点 。 1在一些简单的情况下,您的编译器可能会警告您正在调用未定义的行为,但在一般情况下则不行。

但是,如果您正在编写“有趣”的代码,例如您的示例,那么您通常只会违反序列点要求。 语言标准可以对诸如此类的代码(这是Java所使用的语言)施加特定约束,但是没有很大的好处,以及阻止某些类型的优化的潜在缺点。


1. C ++ 11中的术语略有变化,但我认为原理基本相同。

在将它们发现为错误之前,如何才能看到这些“问题”?

以最严格的级别编译程序,并将所有警告的设置指向为错误。 大多数主流编译器都会指出由于序列点而导致的未定义行为错误。

使用gcc,您可以使用:

 -Wsequence-point 

这将指出序列点问题。 请注意,如果使用-Wall ,则默认启用它。

当然,最好的方法是尝试编写更易读的代码,避免序列点错误冒险