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

C语言中printf参数求值顺序未指定时,errno与strerror()的行为疑问

关于printf参数求值顺序与errno的未指定行为问题

你的问题切中了C语言里一个容易被忽略的未指定行为点,咱们一步步拆解清楚:

首先明确结论:这段代码的行为确实属于C标准定义的「未指定行为」,你无法保证输出的errno值一定是fopen失败时的原始错误码,原因如下:

  • 函数参数的求值顺序未指定:C标准明确规定,函数调用中各个实参的求值顺序是未指定的——编译器完全可以自由选择先计算errno,再调用strerror(errno),或者反过来先调用strerror,再读取errno的值。

  • strerror可能修改errno:虽然strerror的主要作用是返回对应错误码的描述字符串,但如果传入的errno值是无效的(比如某些自定义的错误码),部分实现的strerror会将errno设置为EINVAL。如果编译器选择先调用strerror(errno),那么当后续读取errno参数时,它的值已经被strerror修改,导致输出的错误码和fopen失败时的原始值不一致。

  • 两种可能的执行路径:

    • 若编译器先读取errno的值并保存到printf的参数列表中,再调用strerror:此时即使strerror修改了errno,输出的第一个errno仍然是fopen失败时的原始值,结果符合预期。
    • 若编译器先调用strerror(errno),再读取errno:此时如果strerror修改了errno,输出的errno就变成了strerror修改后的值,和原始错误码不符。

因为C标准没有强制要求参数的求值顺序,编译器可以任选一种方式实现,所以这段代码的行为是不可预测的——你不能依赖某一种执行顺序来保证输出正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 20:42:28