2013-02-22 100 views
2

我有一个很小的代码,但我无法得到为什么输出是这样的。
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

+0

现在缩进请 – ogzd 2013-02-22 15:21:15

+1

可能重复[参数评估顺序在C调用函数之前](http://stackoverflow.com/questions/376278/parameter-evaluation-order-before-a-function-calling-in -c) – unwind 2013-02-22 15:21:58

+0

用'gcc -Wall myprog.c -o myprog'和* gcc *编译你的代码会好心告诉你*警告:'a'上的操作可能是未定义的* – 2013-02-22 15:30:17

回答

4

中所标示的重复接受的答案不正确。


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

原因未定义行为。它试图修改参数a而没有中间的顺序点。此外,重要的是要注意函数参数的评估顺序是未指定。它可以是:

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

如果你正在使用gcc,你可以使用警示标志-wsequence-point向您发出警告序列点相关的不确定的行为。


在GCC如果你在严格的警告级别编译程序,编译器会给你这个诊断:

prog.c:10:18: error: operation on ‘a’ may be undefined [-Werror=sequence-point]
prog.c:10:18: error: operation on ‘a’ may be undefined [-Werror=sequence-point]


参考:

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.

注意,报价仅说有实际的函数调用前序列来看,它并不意味着存在的子表达式参数评价之间的序列点。

+0

@pce:它是**未定义的行为**和**不是未指定的行为**。证明在您引用的引用* C99§6.5.2。2p10 *表示在函数调用之前有一个序列点,它没有说在评估子表达式参数之间有一个序列点。 – 2013-02-22 15:35:54

+0

@pce您如何看待C11§6.5p2? – Sebivor 2013-02-22 15:45:22

+0

@modifiablelvalue hehe,C11太棒了。^ – pce 2013-02-22 16:11:20

1

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

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.

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

+0

Thanx to all。我还看到很多消息来源,我们无法说出指定的序列,但有一个神话,参数评估是从左到右,而传球是从右到左。是这样吗? – 2013-03-03 10:34:53