如何在函数调用中评估参数?

San*_*dip 3 c

考虑以下代码:

void res(int a,int n)
{
    printf("%d %d, ",a,n); 
}

void main(void) 
{
    int i; 
    for(i=0;i<5;i++)
        res(i++,i);
    //prints 0 1, 2 3, 4 5

    for(i=0;i<5;i++)
        res(i,i++);
    //prints 1 0, 3 2, 5 4
}
Run Code Online (Sandbox Code Playgroud)

查看输出,似乎每次都不会从右到左评估参数.到底发生了什么?

Mic*_*urr 7

未指定函数调用中参数的评估顺序.编译器可以按照它可能决定的顺序对它们进行评估.

从C99标准6.5.2.2/10"函数调用/语义":

函数指示符的评估顺序,实际参数和实际参数中的子表达式是未指定的,但在实际调用之前有一个序列点.

如果您需要确保特定订购,使用临时工具是通常的解决方法:

int i; 
for(i=0;i<5;i++) {
    int tmp = i;
    int tmp2 = i++;

    res(tmp2,tmp);
}
Run Code Online (Sandbox Code Playgroud)

更重要的是(因为它导致未定义的行为,而不仅仅是未指定的行为)是您通常不能在表达式中多次使用操作数来增量/减量运算符.那是因为:

在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算来修改一次.此外,先前的值应该只读以确定要存储的值.(6.5/2"表达式")