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

GCC报的‘sequence point’未定义行为警告在C语言中是否有效?

关于两段C代码的未定义行为分析

代码1:p = buf + sprintf(p=buf, "%d", 123);

这段代码的行为是定义良好的,不属于未定义行为。

C标准明确规定,函数调用存在两处序列点:一是所有参数求值完成后、函数体执行前;二是函数返回后、调用者表达式继续执行前。在这段代码中:

  • 先完成sprintf参数p=buf的求值(包含将p修改为buf的副作用),随后到达函数调用的序列点;
  • 执行sprintf函数并返回3,之后到达函数调用结束的序列点;
  • 最后计算buf + 3并将结果赋值给p。

两次对p的修改被函数调用的序列点明确分隔,操作顺序完全确定,符合C标准要求。gcc的警告属于保守性提示,实际不存在未定义行为。

代码2:p += sprintf(p=buf, "%d", 123);

这段代码属于未定义行为,与gcc的警告一致。

p += x在C中等价于p = p + x,展开后代码变为p = p + sprintf(p=buf, "%d", 123);。此时右边表达式包含两个关键操作:

  1. 读取p的当前值(用于计算p + ...);
  2. 在sprintf参数中修改p的值(p=buf)。

根据C标准,赋值运算符的左右操作数求值顺序未指定,且右边表达式内部的子表达式求值顺序也未指定——编译器可选择先读取p的旧值再修改p,或先修改p再读取新值,两种情况会产生完全不同的结果。由于这两个操作(读取和修改p)之间没有序列点分隔,属于未排序操作,因此触发未定义行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 06:50:26