You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++赋值两侧前后缀自增的求值顺序及未定义行为判定

结论

你给出的两段代码的行为要分C++版本判定:

C++17及更高版本

两段代码均不属于未定义行为,行为有明确规则约束。

规则依据

  1. 优先级规则(所有C++版本通用):
    • 后缀自增++ > 前缀自增++ > 加法+ > 复合赋值+=,因此两段代码的表达式都会被分组为(++y) += (x + y + (z++))的结构。
  2. C++17新增的求值顺序规则:

    对于复合赋值运算符E1 op= E2,右操作数E2的所有值计算和副作用,都先序于左操作数E1的所有值计算和副作用;赋值操作本身的副作用,先序于整个表达式的值计算。
    同时规则明确:前缀自增的副作用会在其值计算前完成,后缀自增的副作用会在其值计算后立即完成。

第二段代码执行流程(和你给出的输出5完全匹配)

初始值:x=1, y=1, z=1

  1. 先对+=的右操作数x + y + z++求值:
    • z++先返回z的原值1,随后z的副作用生效,z变为2
    • 此时y仍为1,求和结果为1 + 1 + 1 = 3,右操作数求值完成
  2. 再对+=的左操作数++y求值:
    • 前缀自增先修改y的值为2,返回y的左值
  3. 执行复合赋值:y = 2 + 3 = 5,最终输出结果为5

第一段代码说明

你注释里第一段代码输出6,是不符合C17规则的:按照C17规则,第一段代码右操作数先求值得到1+1+1=3,左操作数++y把y改成2后赋值,最终结果应该是5。你得到的6是C++17之前版本的编译器行为。

C++17之前的版本

两段代码均属于未定义行为。

依据

C++17之前的标准没有规定复合赋值运算符左右操作数的求值顺序,标量y在两个相邻序列点之间被多次修改(前缀自增、复合赋值两次修改y),且对y的读取操作和修改操作之间没有顺序约束,符合未定义行为的判定条件,不同编译器、不同编译选项都可能得到不同的输出结果,你测试得到第一个输出6就是编译器优先对左操作数++y求值的结果。


内容的提问来源于stack exchange,提问作者Peter Green

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 19:36:03