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

标签 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
}

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

最佳答案

函数调用中参数的求值顺序是未指定的。编译器可以按照它可能决定的任何顺序评估它们。

来自 C99 标准 6.5.2.2/10“函数调用/语义”:

The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.

如果您需要确保特定的顺序,使用临时文件是通常的解决方法:

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

    res(tmp2,tmp);
}

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

Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored. (6.5/2 "Expressions")

关于c - 如何在函数调用中评估参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2420685/

相关文章:

c - 在 C 中为具有字符指针的结构分配内存

python - 如何在 C/C++ 应用程序中使用 Pygtk?

c - 为什么我不能传递链的地址?斯特托尔

c - 分配大字符串时大小 1 的读取无效

sockaddr_in 结构中 "localhost"的 C Linux 宏?

c - gcc:目标文件或库中的重复标识符

c - fork()-ing a'la popen 时检测到找不到程序

c - 当零是计算器程序中的操作数时没有结果

c - 如何将 argv[k] 变成另一个字符串?

c - C 程序调用的 ARM 汇编代码出现段错误