c函数参数评估和传递

时间:2013-02-22 15:19:56

标签: c

我有一个很小的代码,但我无法理解为什么输出就是这样。
这是

#include <stdio.h>

int f(int i, int j, int k);

int main(int argc, char const *argv[])  
{  
    int a;   
    printf("enter a\n");  
    scanf("%d",&a);  
    f(a,a++,a++);  
    printf("%d \n",a );  
    return 0;  
}  

int f(int i, int j, int k)  
{  
    printf("function arguments \n");  
    printf("%d %d %d\n",i,j,k );  
}   

输入:4
输出:6 5 4

2 个答案:

答案 0 :(得分:4)

标记副本中接受的答案不正确。


f(a,a++,a++); 

导致未定义的行为。它试图在没有插入序列点的情况下修改参数a。此外,重要的是要注意函数参数的评估顺序是未指定。它可以是:

  • 从左到右或
  • 从右到左或
  • 编译器选择的任何神奇的顺序。

如果您正在使用GCC,您可以使用警告标志-wsequence-point来警告您与序列点相关的未定义行为。


在GCC中如果您在最严格的警告级别编译程序,编译器将为您提供此诊断:

  

prog.c:10:18:错误:'a'上的操作可能未定义[-Werror = sequence-point]
  prog.c:10:18:错误:'a'上的操作可能未定义[-Werror = sequence-point]


参考:

C99标准§6.5.2.2:
第10段:

  

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

请注意,引用只表示在实际函数调用之前有一个序列点,并不意味着在表达子表达式参数之间存在一个序列点。

答案 1 :(得分:1)

f(a,a++,a++);似乎是未定义的行为,因为:

  

如果标量对象的副作用相对于其中任何一个都没有排序   对同一个标量对象或值有不同的副作用   使用相同标量对象的值进行计算,行为是   未定义。如果有多个允许的排序   表达式的子表达式,如果这样的话,行为是不确定的   任何顺序都会出现无序的副作用。

使用未定义的行为时,C标准没有要求。