You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

调用存在副作用且执行顺序未指定的函数是否属于未定义行为?

关于printf("foo") + printf("bar")是否属于未定义行为的解答

好问题!这确实是C/C++里很容易和“未定义行为”搞混的场景,咱们来把它拆解清楚:

首先,先回顾你提到的x = x++ + ++x这类未定义行为的核心:在同一个序列点内,对同一个变量进行了多次修改,而且这些修改之间没有明确的顺序约束。这种情况下,标准完全不限制编译器的处理方式,可能会出现各种不可预测的结果,甚至触发奇怪的内存操作,属于绝对要避免的情况。

printf("foo") + printf("bar")的情况,本质上是未指定行为(unspecified behavior),和未定义行为有本质区别:

  • 未定义行为是标准完全放弃约束,编译器可以任意发挥(结果可能完全离谱);
  • 未指定行为则是标准明确列出了几种合法的结果,但不强制要求编译器选择哪一种,所有可能的结果都是符合标准的,不会出现错误的执行逻辑。

具体到这个例子:C标准规定,+这类普通二元运算符的两个操作数的求值顺序是未指定的——编译器既可以先计算左边的printf("foo")(输出"foo",返回值是3),再计算右边的printf("bar")(输出"bar",返回值是3),最终表达式结果是6;也可以反过来先算右边再算左边,输出"barfoo",结果同样是6。不管哪种顺序,都是符合标准的,不会出现比如输出"fobar"这种混乱的结果,更不会导致程序崩溃。

简单总结:这种情况不属于未定义行为,只是求值顺序未指定,输出顺序不确定,但所有可能的结果都是合法的。

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

火山引擎 最新活动