"x = ++ x"是不是真的未定义?

Mag*_*rmo 12 c++ operator-precedence coverity-prevent

我在项目中使用Coverity Prevent来查找错误.

它报告此表达式的错误(变量名称当然已更改):

x=
   (a>= b) ?
   ++x: 0;
Run Code Online (Sandbox Code Playgroud)

消息是:

EVALUATION_ORDER缺陷:在" x=(a>= b) ? ++x: 0;"中," x"写在" x"(赋值LHS)中并用" (a>= b) ? ++x: 0;" 写入,但副作用发生的顺序是不确定的,因为没有中间序列点.消息结束

虽然我可以理解" x = x++"是不确定的,但这对我来说有点困难.这个是假阳性吗?

AnT*_*AnT 28

条件运算符?:在条件评估(第一个操作数)和第二个或第三个操作数的评估之间有一个序列点,但在评估第二个或第三个操作数它没有专用的序列点.这意味着x此示例中的两个修改可能存在冲突(未由序列点分隔).所以,Coverity Prevent是对的.

你在这方面的陈述几乎相当于

a >= b ? x = ++x : x = 0;
Run Code Online (Sandbox Code Playgroud)

与...中的问题相同x = ++x.

现在,你问题的标题似乎暗示你不知道是否x = ++x未定义.确实未定义.由于同样的原因x = x++尚未定义,因此未定义.简而言之,如果在一对相邻序列点之间多次修改相同的对象,则行为是不确定的.在这种情况下x,通过赋值修改,并且++没有序列点将这些修改彼此"隔离".所以,行为是不确定的.这方面++xx++这方面完全没有区别.


Ste*_*end 12

无论消息的准确性如何,替换有问题的代码都x= (a>= b) ? x+1: 0;可以实现相同的目的而不会产生任何混淆.如果工具混淆了,那么下一个查看此代码的人也可能会这样.

这假设x没有一个重载的增量运算符,它具有您在此处依赖的副作用.

  • 如果它有一个重载的增量运算符@Steven,那么就不再存在任何未定义的行为问题.在赋值运算符开始之前,将对增量运算符进行全面计算. (2认同)

Ama*_*osh 8

该语句在命中序列点之前x = ++x;写入变量x两次,因此行为未定义.