调用C和未定义/未指定的行为函数时顺序点(Sequence points when calling

2019-07-29 20:48发布

我想拖住我的序列点的理解用C - 只是想检查一番。 目前我认为(1)是未定义的,而(2)是仅仅未指定的,即在(2)中,评价论据后是序列点的基础上, gh (因此我们不修改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;
}

编辑:

看来这里的关键点是编译器是否可以自由地执行这两个增量之前gh叫-我从下面的答案的理解是,它是,但我会很感激确认是这种情况。

Answer 1:

不,每6.5.2.2 10存在的子表达式参数的评价之间没有顺序点,就在实际调用之前。

看它的方法之一是,它是不确定的行为是否是不确定的; 如果实现序列两个++i任何呼叫之前的子表达式gh然后行为是不确定的,但如果++i子表达式尽可能晚地进行评估(立即调用之前gh分别),则行为是未指定。 然而,因为实现总是随意任何允许未指定的行为之间做出选择,则总的结果是不确定的。



Answer 2:

不正确。 序列点指定的操作允许订购的部分订单 。 在情况(2)中,有序列点:

  1. 在在该行的末尾的分号(1)
  2. 的自变量的评价后g (即, ++i ),但之前调用g
  3. 的参数的评估后h (即++i ),但在调用之前h
  4. 的参数的评估后f (后即fg已经返回),但在调用之前f
  5. 从返回后f

因此,部分顺序是这样的,从顶部到底部:

    1
   / \
  /   \
 2     3
  \   /
   \ /
    4
    |
    | 
    5

图2和3不与相对于彼此排序,因为自变量的评价的顺序是不确定的。 因为i被序列点1和4之间改性两次,则该行为是未定义的。



文章来源: Sequence points when calling functions in C and undefined/unspecified behaviour