【发布时间】:2016-04-10 19:32:19
【问题描述】:
我读到here 有一个序列点:
在与输入/输出转换格式说明符关联的操作之后。例如,在表达式
printf("foo %n %d", &a, 42)中,在打印42之前计算%n之后有一个序列点。
但是,当我运行this code:
int your_function(int a, int b) {
return a - b;
}
int main(void) {
int i = 10;
printf("%d - %d - %d\n", i, your_function(++i, ++i), i);
}
我得到的不是我所期望的:
12 - 0 - 12
意味着没有为转换格式说明符创建序列点。 http://en.wikipedia.org 是错误的,还是我误解了什么,或者在这种情况下 gcc 不兼容(顺便说一下 Visual Studio 2015 会产生相同的意外结果)?
编辑:
我知道your_function 的参数被评估并分配给参数的顺序是未定义的。我不是在问为什么我的中项是 0。我是在问为什么其他两个项都是 12。
【问题讨论】:
-
根据this,这是未定义的行为。我也相信
your_function(++i, ++i)也是未定义的行为。 -
your_function(++i, ++i)显然是 UB。 -
标准引用所描述的序列点在
printf()函数被调用后位于其主体内。在调用printf()函数之前,您在调用序列中有极端未定义的行为——这意味着任何结果都是可接受的(包括您得到的结果)。 -
@lurker:两个增量都必须在调用
your_function()之前完成;在评估函数调用的参数之后有一个序列点,因此参数列表中的副作用是完整的。不清楚的是相同的值是否被两次传递给your_function()——它是未定义的;传递给printf()的其他两个值i是否在另一个函数调用的双倍递增之前、之后或期间进行评估也是未定义的。 -
简单点就是函数参数的求值顺序是unspecified。
标签: c++ c printf undefined-behavior sequence-points