确定子程序参数评估顺序

时间:2012-12-02 23:10:58

标签: c subroutine

我正在用C编写一个程序来确定子程序参数的计算顺序。

到目前为止我的内容如下:

int i=1;
printf("%d %d %d\n", i++, i++, i);

但我不确定如果我在正确的道路上,或者用Ruby这样的其他语言编写会更容易。

如何用C(或Ruby)编写一个程序来确定子程序参数的计算顺序?

2 个答案:

答案 0 :(得分:4)

对printf()函数的参数的评估顺序是未指定。因此,您无法以可评估的顺序确定它们的评估顺序。如果这是您想要确定的内容,那么您可能会选择评估顺序明确定义的语言。

此外,您的代码具有未定义的行为,因为您在没有插入序列点的情况下多次修改i

答案 1 :(得分:3)

在不调用未定义行为的情况下执行此操作的方法是在评估每个参数时简单地打印消息:

#include <stdio.h>

static void foo(int a, int b, int c) {}

static int argument(int n)
{
    printf("Argument %d.\n", n);
    return n;
}

int main(void)
{
    foo(argument(0), argument(1), argument(2));
    return 0;
}

但是,这只会向您显示程序的一个特定执行中的参数评估顺序。参数评估的顺序不是由C标准指定的,并且可能由于各种原因而改变。例如,如果传递一个函数简单参数,编译器可能会从头到尾对它们进行评估,以便它可以按照在该平台上调用子例程所需的顺序轻松地将它们放在堆栈中。但是假设,使用相同的编译器版本和编译开关,您可以向函数传递一些复杂的参数,其中一些参数具有公共子表达式。编译器可能会决定首先评估这些参数,以利用公共子表达式。

编译器甚至可以评估一个参数的一部分,然后是另一个参数的一部分,然后是第一个参数的一部分,然后是第三个参数,然后计算函数调用之前的表达式(保留提供的序列点行为),然后完成第二个参数参数。

参数评估的顺序不是你可以依赖的。