C语言的评估顺序

问题描述 投票:0回答:1
  1. x+=x*=x是未定义的行为吗?
  2. 有人可以在Order of evaluation中解释此规则吗?什么是“单项评估”? “单次评估”的对立面是什么?

    14)对于不确定顺序的函数调用,复合赋值运算符的操作以及递增和递减运算符的前缀和后缀形式都是单个求值。

c operator-precedence
1个回答
1
投票

1)是。

C17 6.5.16赋值运算符,第3节

操作数的求值是无序列的。

由于C17 6.5§2而将其设为UB

如果相对于相同标量对象的不同副作用或使用相同标量对象的值进行的值计算,相对于标量对象的副作用未排序,则行为未定义。

每次分配都是副作用。 C99具有相同的规则,但更容易理解:

C99 6.5§2

在上一个和下一个序列点之间,对象应具有其存储的值通过对表达式的求值最多只能修改一次。此外,先验价值应该是只读的,以确定要存储的值。


2)所有具有C11排序更改的文本都很难阅读。他们使用未在任何地方正式定义的术语,例如“单一评估”。

规范性文本为C17 6.5.15.2§3

形式为E1 op = E2的复合赋值等同于简单赋值表达式E1 = E1 op(E2),除了左值E1仅被评估一次,且对于不确定顺序的函数调用,复合赋值的操作是单个求值。

我想这只是意味着像int x; ... x += 1之类的操作应导致机器代码如下:

  • 将1存储在寄存器中
  • 添加x进行注册
  • 将寄存器写入x

否则,假设某些东西在更新x的那些操作之间获得了顺序。但是复合赋值不是原子的,所以我不太理解这里的标准。

© www.soinside.com 2019 - 2024. All rights reserved.