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

成员函数调用中this实参与其他实参的求值顺序及空指针UB问题

问题解答

这段代码的行为属于未定义行为,无法保证estimate()会在访问model之前被调用,具体原因如下:

核心原因:求值顺序的不确定性

对于表达式model->set(estimate(model)),它包含两个关键操作步骤:

  • 步骤1:求值model->set——需要通过->操作符解引用空指针model,这一步本身就违反了C++标准,属于未定义行为。
  • 步骤2:求值实参estimate(model)——调用函数检查model是否为空,为空则抛出异常。

不同C++版本的求值规则

  • C++17之前:编译器可以自由选择先执行步骤1还是步骤2。如果先执行步骤1,会直接触发未定义行为;如果先执行步骤2,会抛出异常进入catch块。但标准没有规定固定顺序,因此整个表达式的行为是未定义的。
  • C++17及之后:标准明确规定,函数调用的前缀表达式(即model->set)会在所有实参表达式之前求值。这意味着会先执行步骤1的空指针解引用,直接触发未定义行为,estimate(model)根本不会被调用。

额外说明

即使set函数内部没有访问this指向的成员变量,通过空指针调用非虚成员函数本身就是C++标准定义的未定义行为,和函数内部逻辑无关。

修复方案

正确的做法是先调用estimate()完成指针检查,确认有效后再调用成员函数:

try
{
    std::shared_ptr<Model> model;
    int x = estimate(model); // 先执行检查,空指针直接抛出异常
    model->set(x); // 此时model必然非空,调用安全
}
catch (const std::runtime_error& e)
{
    std::cout << e.what();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 10:13:23