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

在同一表达式中解引用并递增指针p是否会导致未定义行为?

表达式中指针读写的未定义行为疑问

在Bjarne Stroustrup所著《C++编程原理与实践》第8.6.1章中提到:子表达式的求值顺序由优化器导向的规则决定,需遵循规则:若在表达式中修改变量值,请勿在同一表达式中对其进行两次读写,并列举了如下未定义行为示例:

v[i] = ++i;                                       // don’t: undefined order of evaluation
v[++i] = i;                                       // don’t: undefined order of evaluation
int x = ++i + ++i;                           // don’t: undefined order of evaluation
cout << ++i << ' ' << i << '\n';      // don’t: undefined order of evaluation
f(++i,++i);                                    // don’t: undefined order of evaluation

此类代码因编译器、平台或优化设置不同可能产生不同结果,且部分编译器不会发出警告。

之后发现一段用于输出对象字节表示的代码:

template <typename T>
void print_bytes(const T& input, std::ostream& os = std::cout)
{
    const uint8_t* p = reinterpret_cast<const uint8_t*>(&input); 
    os << std::hex << std::showbase;
    os << "[";
    for (unsigned int i = 0; i < sizeof(T); ++i)
    {
        os << std::setw(5) << static_cast<int>(*(p++)) << " ";
    }
    os << "]" << std::endl;
    os << std::dec << std::noshowbase;
}

其中os << std::setw(5) << static_cast<int>(*(p++)) << " ";一行中,指针p在同一表达式中被解引用并递增,请问该写法是否会因编译器、平台不同产生行为差异,是否属于未定义行为?


结论:这段代码不属于未定义行为,不会因编译器/平台差异产生行为差异

原因如下:

  1. 链式operator<<是独立函数调用:C++中,a << b << c的本质是operator<<(operator<<(a, b), c),每个operator<<调用都是一个独立操作,前一个调用的所有副作用(比如变量修改)都会在后续调用开始前完全完成。
  2. 后置递增运算符语义明确:*(p++)的行为固定——先解引用当前指针p指向的值,再将p自增1,这个操作的求值顺序和副作用没有歧义。
  3. 对比书中的未定义行为:书中的例子都是在同一个运算符的操作数之间(比如++i + ++i)或同一函数的参数列表中(比如f(++i, ++i))存在无明确顺序的读写操作,而这段代码的链式输出是多个有序的函数调用,不存在这种无序冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 19:07:07