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

C++中v[i] = ++i;是否为良定义行为?各版本标准差异咨询

表达式v[i] = ++i;在C++各标准中的行为解析

核心结论

  • C11/C14:未定义行为(UB)
  • C17/C20:良定义行为

你推导中忽略的关键点,是不同C标准中赋值运算符求值顺序规则的差异,以及C11/14中左右操作数求值的无排序关系。


分版本规则详解

1. C11/C14:未定义行为的原因

在C11和C14中,赋值运算符的规则为:

赋值操作被排序于左右操作数的值计算之后,但左右操作数之间的求值顺序是不确定的(unspecified)

对于表达式v[i] = ++i;,涉及两个关键操作:

  • 右操作数++i:对i执行修改(副作用),并产生修改后的i的值。
  • 左操作数v[i]:需要读取i的值计算数组下标,进而访问v的元素。

由于左右操作数的求值顺序不确定,++i修改i的动作与v[i]读取i的动作之间没有明确的排序关系。而C++11/14标准规定:若对同一对象的修改操作与读取操作无显式排序,行为即为未定义,因此该表达式属于UB。

2. C++17:规则修改后变为良定义

C++17对赋值运算符的求值顺序做了明确强化:

赋值运算符的右操作数的求值被排序于左操作数的求值之前

同时,前置自增运算符++i的规则也明确:

前置自增的副作用(修改i)被排序于该表达式的值计算之前

结合这两条规则,v[i] = ++i;的执行顺序被严格确定:

  1. 执行++i:先修改i的值(副作用),再计算得到修改后的i的值(右操作数的值计算)。
  2. 计算左操作数v[i]:读取已修改后的i的值,确定数组下标并定位到v的对应元素。
  3. 执行赋值:将右操作数的值(新i)赋给左操作数定位到的数组元素。

所有对i的修改和读取操作都有明确排序关系,行为完全确定,属于良定义。

3. C20:延续C17的规则

C20未修改赋值运算符和前置自增的求值顺序规则,因此v[i] = ++i;的行为与C17一致,属于良定义。


关于C++核心指南ES.43的说明

C核心指南ES.43中指出该表达式存在未定义行为,大概率是基于C17之前的标准编写的。核心指南的部分内容未及时跟进C17及之后的规则变化,因此在现代C标准中,该表达式的行为已明确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 08:10:32