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

C++中a=a+deg1(&a)运行结果为40而非20的原因解析

问题根因

你得到40的结果不是编译器错误,是C++表达式求值规则和函数副作用共同导致的,具体拆解如下:

核心代码执行流分析

先看deg1函数的逻辑:

int deg1(int*p){
    *p = 20; // 直接修改指针指向的原变量,副作用会立刻生效
    int i = *p;
    return i; // 固定返回20
}

关键问题出在a = a + deg1(&a);这行:

  • 在C++17标准正式发布前,加法运算符+的左右两个操作数的求值顺序是未指定的:编译器可以自由选择先读左边的a,还是先执行右边的deg1(&a)函数调用,两种执行顺序都符合语言标准。
  • 你当前使用的编译器选择了先执行右侧的函数调用,具体执行步骤为:
    • 第一步:调用deg1(&a),进入函数后直接把原变量a的值从初始的10修改为20,函数最终返回值为20
    • 第二步:读取加法左侧操作数a的值,此时a已经被deg1的副作用修改为20,不再是初始的10
    • 第三步:执行加法运算:20 + 20 = 40,将结果赋值给a,因此最终输出a的值为40

如果你换用其他选择了“先读左操作数再调用函数”的旧编译器,这行代码会得到10+20=30的结果,这同样是符合标准的,不存在对错,只说明这类代码本身存在歧义,属于不良实践。

为什么b的计算结果符合预期

你写的b = b +deg2(b);结果固定为60,不会出现歧义,原因是deg2是值传递:

int deg2(int x){
    return x * 2; // 操作的是b的拷贝x,不会修改原变量b
}

不管编译器先读b的值,还是先调用deg2,原变量b的值始终是初始的20,deg2固定返回40,求和结果永远是20+40=60,不会出现不确定的结果。

编码建议

不要在同一个表达式中,既通过指针/引用的副作用修改某个变量,又在表达式的其他位置读取这个变量的值,这类代码会依赖编译器的求值顺序选择,极易出现和预期不符的运行结果,可维护性极差。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.20 16:15:51