序列点来自哪里?

Art*_*nek 9 c c++ sequence-points

我知道写点东西

++a = a++;
Run Code Online (Sandbox Code Playgroud)

不仅是不可读的,而且还违反了c/c ++序列点.

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

Che*_*Alf 9

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

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

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

提示:const尽可能洒到处.

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


Oli*_*rth 8

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

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


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


Alo*_*ave 5

在将它们视为错误之前,如何才能看到这些"问题"?

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

使用gcc,您可以使用:

-Wsequence-point
Run Code Online (Sandbox Code Playgroud)

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

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

  • @chris:`-Wall`默认启用它,正如我已经提到的那样. (2认同)