我想拖住我的序列点的理解用C - 只是想检查一番。 目前我认为(1)是未定义的,而(2)是仅仅未指定的,即在(2)中,评价论据后是序列点的基础上, g
和h
(因此我们不修改i
之间两次序列分),但的参数计算顺序f
仍然是不确定的。 我的理解是正确的吗?
#include <stdio.h>
int g(int i) {
return i;
}
int h(int i) {
return i;
}
void f(int x, int y) {
printf("%i", x + y);
}
int main() {
int i = 23;
f(++i, ++i); // (1)
f(g(++i), h(++i)); // (2)
return 0;
}
编辑:
看来这里的关键点是编译器是否可以自由地执行这两个增量之前g
或h
叫-我从下面的答案的理解是,它是,但我会很感激确认是这种情况。
不,每6.5.2.2 10存在的子表达式参数的评价之间没有顺序点,就在实际调用之前。
看它的方法之一是,它是不确定的行为是否是不确定的; 如果实现序列两个++i
任何呼叫之前的子表达式g
或h
然后行为是不确定的,但如果++i
子表达式尽可能晚地进行评估(立即调用之前g
和h
分别),则行为是未指定。 然而,因为实现总是随意任何允许未指定的行为之间做出选择,则总的结果是不确定的。
不正确。 序列点指定的操作允许订购的部分订单 。 在情况(2)中,有序列点:
- 在在该行的末尾的分号(1)
- 的自变量的评价后
g
(即, ++i
),但之前调用g
- 的参数的评估后
h
(即++i
),但在调用之前h
- 的参数的评估后
f
(后即f
和g
已经返回),但在调用之前f
- 从返回后
f
因此,部分顺序是这样的,从顶部到底部:
1
/ \
/ \
2 3
\ /
\ /
4
|
|
5
图2和3不与相对于彼此排序,因为自变量的评价的顺序是不确定的。 因为i
被序列点1和4之间改性两次,则该行为是未定义的。
文章来源: Sequence points when calling functions in C and undefined/unspecified behaviour