我正在用 C 编写一个程序,该程序确定评估子例程参数的顺序。
到目前为止,我有以下内容:
int i=1;
printf("%d %d %d\n", i++, i++, i);
但我不确定我是否走在正确的道路上,或者用 Ruby 等不同的语言编写会更容易。
如何用 C(或 Ruby)编写一个程序来确定评估子例程参数的顺序?
我正在用 C 编写一个程序,该程序确定评估子例程参数的顺序。
到目前为止,我有以下内容:
int i=1;
printf("%d %d %d\n", i++, i++, i);
但我不确定我是否走在正确的道路上,或者用 Ruby 等不同的语言编写会更容易。
如何用 C(或 Ruby)编写一个程序来确定评估子例程参数的顺序?
printf() 函数的参数评估顺序未指定。因此,您无法以可移植的方式确定它们的评估顺序。如果这是您想要确定的,那么也许您会选择一种评估顺序明确的语言。
此外,当您多次修改而没有中间序列点时,您的代码具有未定义的行为。i
在不调用未定义行为的情况下执行此操作的一种方法是在评估每个参数时简单地打印一条消息:
#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 标准未指定参数评估的顺序,并且可能由于各种原因而更改。例如,如果您传递一个函数的简单参数,编译器可能会从后到先评估它们,以便它可以轻松地将它们按照在该平台上调用子例程所需的顺序放入堆栈中。但是假设,使用相同的编译器版本和编译开关,您向函数传递了一些复杂的参数,其中一些具有公共子表达式。编译器可能决定首先评估这些参数,以利用公共子表达式。
编译器甚至可以计算一个参数的一部分,然后是另一个参数的一部分,然后是第一个参数的一部分,然后是第三个参数,然后计算函数调用之前的表达式(假设序列点行为被保留),然后完成第二个参数。
参数评估的顺序不是您可以依赖的。