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

C++17中if条件内函数调用里赋值是否为定义行为?

C++17中短路赋值写法的行为定义分析

这种写法的行为在C17中是完全有定义的,核心依据是C标准里的短路求值规则:逻辑或运算符||会先严格求值左侧操作数,只有当左侧结果为false时,才会继续求值右侧操作数。这个规则并非C17新增,在更早的C标准(如C11、C03)中就已经存在。

两段代码的具体行为分析

第一段:std::map版本

void myFunction (std::map<int, int> my_map)
{
    int linked_element;
    if (my_map[linked_element = firstIndex] != 0
        || my_map[linked_element = secondIndex] != 0)
    {
        // do some stuff with linked_element
    }
}

执行顺序严格遵循短路规则:

  1. 先执行linked_element = firstIndex,完成赋值
  2. 调用std::map::operator[]:如果firstIndex不存在于map中,会自动插入一个值为0的元素
  3. 判断返回值是否不等于0:
    • 若为true,整个条件成立,右侧的赋值和map访问完全不会执行,linked_element的值是firstIndex
    • 若为false,才会执行右侧的linked_element = secondIndex,重复上述map访问和判断逻辑

第二段:std::set版本

void myFunction (std::set<int> my_set)
{
    int linked_element;
    if (my_set.find(linked_element = firstIndex) != my_set.end()
        || my_set.find(linked_element = secondIndex) != my_set.end())
    {
        // do some stuff with linked_element
    }
}

逻辑类似但不会修改容器:

  1. 先执行linked_element = firstIndex
  2. 调用std::set::find查找该值:
    • 若找到(迭代器不等于end()),条件成立,右侧代码不执行,linked_element值为firstIndex
    • 若未找到,才会执行右侧的赋值和查找操作

关于写法的合理性

虽然行为有定义,但这种写法可读性极差,维护者很容易忽略条件判断中嵌有赋值操作,后续修改时极易引入bug。更清晰的替代写法应该将赋值与判断逻辑拆分:

比如std::set的C++17兼容写法:

void myFunction(std::set<int> my_set)
{
    int linked_element;
    auto it = my_set.find(firstIndex);
    if (it != my_set.end()) {
        linked_element = firstIndex;
    } else {
        it = my_set.find(secondIndex);
        if (it != my_set.end()) {
            linked_element = secondIndex;
        } else {
            return;
        }
    }
    // do some stuff with linked_element
}

对于std::map,如果不想自动插入不存在的键,应该用find代替operator[],避免不必要的容器修改:

void myFunction(std::map<int, int> my_map)
{
    int linked_element;
    auto it = my_map.find(firstIndex);
    if (it != my_map.end() && it->second != 0) {
        linked_element = firstIndex;
    } else {
        it = my_map.find(secondIndex);
        if (it != my_map.end() && it->second != 0) {
            linked_element = secondIndex;
        } else {
            return;
        }
    }
    // do some stuff with linked_element
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 08:50:38