调用存在副作用且执行顺序未指定的函数是否属于未定义行为?
关于
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




