"x = ++x"它真的是未定义的吗?

发布于 2024-09-17 05:44:44 字数 489 浏览 9 评论 0 原文

我在项目上使用 Coverity Prevent 来查找错误。

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

x=
   (a>= b) ?
   ++x: 0;

消息是:

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

虽然我可以理解“x = x++”是未定义的,但这对我来说有点困难。这是误报吗?

I am using Coverity Prevent on a project to find errors.

It reports an error for this expression (The variable names are of course changed):

x=
   (a>= b) ?
   ++x: 0;

The message is:

EVALUATION_ORDER defect: In "x=(a>= b) ? ++x: 0;", "x" is written in "x" (the assignment LHS) and written in "(a>= b) ? ++x: 0;" but the order in which the side effects take place is undefined because there is no intervening sequence point. END OF MESSAGE

While I can understand that "x = x++" is undefined, this one is a bit harder for me. Is this one a false positive or not?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

平安喜乐 2024-09-24 05:44:44

条件运算符 ?: 在条件(第一个操作数)的求值和第二个或第三个操作数的求值之间有一个序列点,但在求值之后没有专用的序列点第二个或第三个操作数。这意味着此示例中 x 的两个修改可能会发生冲突(不是由序列点分隔)。所以,Coverity Prevent 是正确的。

您在这方面的陈述实际上

a >= b ? x = ++x : x = 0;

x = ++x 中的问题相同。

现在,您的问题的标题似乎表明您不知道 x = ++x 是否未定义。它确实是未定义的。它未定义的原因与 x = x++ 未定义的原因相同。简而言之,如果同一对象在一对相邻序列点之间被修改多次,则行为是未定义的。在这种情况下,x 通过赋值和 ++ 进行修改,并且没有序列点来“隔离”这些修改。因此,行为是未定义的。在这方面,++xx++ 之间完全没有区别。

Conditional operator ?: has a sequence point between evaluation of the condition (first operand) and evaluation of second or third operand, but it has no dedicated sequence point after the evaluation of second or third operand. Which means that two modifications of x in this example are potentially conflicting (not separated by a sequence point). So, Coverity Prevent is right.

Your statement in that regard is virtually equivalent to

a >= b ? x = ++x : x = 0;

with the same problem as in x = ++x.

Now, the title of your question seems to suggest that you don't know whether x = ++x is undefined. It is indeed undefined. It is undefined for the very same reason x = x++ is undefined. In short, if the same object is modified more than once between a pair of adjacent sequence points, the behavior is undefined. In this case x is modified by assignment and by ++ an there's no sequence point to "isolate" these modifications from each other. So, the behavior is undefined. There's absolutely no difference between ++x and x++ in this regard.

缱绻入梦 2024-09-24 05:44:44

无论消息的准确性如何,用 x= (a>= b) 替换有问题的代码? x+1: 0; 达到了相同的目的,没有任何混乱。如果该工具感到困惑,那么也许下一个查看此代码的人也会感到困惑。

这确实假设 x 没有您在此依赖的具有副作用的重载增量运算符。

Regardless of the accuracy of the message, replacing the code in question by x= (a>= b) ? x+1: 0; achieves the same end without any confusion. If the tool is confused then maybe the next person to look at this code will be too.

This does assume that x does not have an overloaded increment operator with side-effects that you rely on here.

水溶 2024-09-24 05:44:44

语句 x = ++x; 在命中 x 写入两次rel="nofollow noreferrer">序列点,因此行为未定义。

The statement x = ++x; writes to the variable x twice before hitting the sequence point and hence the behavior is undefined.

世界和平 2024-09-24 05:44:44

很难想象编译器会生成“x = ++x;”的代码。事实上,它与“++x”的工作方式不同。然而,如果 x 不是易失性的,则编译器处理语句“y = ++x;”是合法的。 as

  y=x+1;
  x=x+1;

语句“x = ++x;” 如果将

  x=x+1;
  x=x+1;

一个算术赋值表达式的目标太快地用作另一个算术赋值表达式的源操作数会导致管道延迟,则前一种优化可能是合理的。如果递增的变量和分配的变量相同,显然是灾难性的。

如果变量“x”是易失性的,我想不出任何代码序列,其中不是故意试图变得刻薄的编译器可以合法地认为“x = x++;”除了读取 'x' 的所有部分一次并将相同的正确值写入 'x' 的所有部分两次之外,具有任何效果。

It is hard to imagine a compiler producing code for "x = ++x;" which would in fact not work the same as "++x". If x is not volatile, however, it would be legal for a compiler to process the statement "y = ++x;" as

  y=x+1;
  x=x+1;

The statement "x = ++x;" would thus become

  x=x+1;
  x=x+1;

If having the destination of one an arithmetic assignment expression get used too quickly as a source operand for another would cause a pipeline delay, the former optimization might be reasonable. Obviously disastrous if the incremented and assigned variable are one and the same.

If variable 'x' is volatile, I can't think of any code sequence where a compiler that wasn't deliberately trying to be mean could legitimately regard "x = x++;" as having any effect other than reading all parts of 'x' exactly once and writing the same correct value to all parts of 'x' exactly twice.

流绪微梦 2024-09-24 05:44:44

我认为从逻辑上讲,如果你写“x=++x”或“x=x++”,无论哪种方式,你都会期望最终结果是 x 比开始时多 1。但让它稍微复杂一点。如果你写“x=x+(++x)”怎么办?这与“x=x+(x+1)”相同吗?或者我们先加一,然后将 x 加到它本身,即“x=(x+1)+(x+1)”?如果我们写“x=(x--)+(x++)”怎么办?

即使您可以编写一个语言规范,为这些结构赋予明确的含义,然后可以干净地实现它,您为什么要这样做呢?在对同一变量的赋值中放置一元增量是没有意义的,即使我们强制赋予它意义,它也没有提供任何有用的功能。就像,我确信我们可以编写一个编译器,它会采用“x+1=y-1”这样的表达式,并弄清楚这实际上意味着“x=y-2”,但为什么要麻烦呢?没有任何收获。

即使我们编写的编译器可以用“x=x++-++x”做一些可预测的事情,程序员也必须知道并理解这些规则。没有任何明显的好处,它只会无缘无故地增加程序的复杂性。

I suppose that logically, if you write either "x=++x" or "x=x++", either way you would expect the end result to be that x is one more than it started as. But make it just a shade more complicated. What if you wrote "x=x+(++x)" ? Is this the same as "x=x+(x+1)" ? Or do we add one first and then add x to itself, i.e. "x=(x+1)+(x+1)"? What if we wrote "x=(x--)+(x++)" ?

Even if you could write a language spec that gave unambiguous meaning to these sort of constructs, and could then implement it cleanly, why would you want to? Putting a unary increment in an assignment to the same variable just doesn't make sense, and even if we forced sense out of it, it provides no useful functionality. Like, I'm sure we could write a compliler that would take an expression like "x+1=y-1" and figure out that that really means "x=y-2", but why bother? There's no gain.

Even if we wrote compilers that did something predictable with "x=x++-++x", programmers would have to know and understand the rules. Without any obvious benefit, it would just add complexity to programs for no purpose.

云淡月浅 2024-09-24 05:44:44

为了理解这一点,您需要对序列点有基本的了解。请参阅此链接:http://en.wikipedia.org/wiki/Sequence_point

对于 = 运算符没有序列点,因此不能保证 x 的值在再次分配给 x 之前会被修改。

In order to understand this you need to have a basic understanding of sequence points. See this link: http://en.wikipedia.org/wiki/Sequence_point

For the = operator there is no sequence point, so there is no guarantee that the value of x will be modified before it is again assigned to x.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文