当我用Google搜索时,我总是得到关于评估顺序的线索,一般说明评估顺序未指定。
我知道参数评估顺序通常在C
中未指定。
我的问题是gcc
中的参数评估顺序,从左到右还是从右到左?
任何资源链接也将受到赞赏......
编辑:消除问题中的含糊不清
嗯,我说的是
时的情况 foo(1+2,2+3,4+9)
首先评估?
是1+2
还是4+9
......就像明智......
我们可以通过在一个gcc编译器中编译它来获得声明吗?或者它在不同的gcc版本中是否也有所不同?
答案 0 :(得分:7)
如果你真的问foo(f1(), f2(), f3())
- 这比foo(1+2, 3+4, 5+6)
更有意思,因为加上1 + 2和3 + 4无论是先完成还是最后一次或随机抽取都不会有效订购。
现在,不幸的是,您不能依赖于f1()
和f2()
以及f3()
以任何特定顺序调用 - 只要每个函数都被称为ONCE,它对订单没问题是任何订单:
f1, f2, f3
f1, f3, f2
f2, f3, f1
f2, f1, f3
f3, f2, f1
f3, f1, f2
(涵盖三个参数的所有排列)。
它完全取决于它“认为最好”的编译器。
我很长一段时间写了一些代码,遇到了这个特殊的问题 - 我有类似的东西:
char foo(char a, char b)
...
if (a =! 'x')
foo(fgetc(f), foo(fgetc(f)));
...
由于我期望首先调用FIRST(左)fgetc()
,然后调用第二fgetc()
,我可以得到正确的行为。它在学校的电脑上运行良好。然后我把代码带回家并尝试在家用电脑上使用它。由于某种原因,它无法正常工作。我花了很长时间才发现foo()
只是被无限调用,因为a
永远不会'x'
,这会停止递归 - 因为'x'
永远不会出现在第二个电话。
那是在两台机器上都使用gcc,但其中一台是sparc(学校计算机),而家里的那台是x86(386,运行OS / 2,这是多久以前)。
解决方案是将其分成几行:
char aa = fgetc(f);
char bb = fgetc(f);
foo(aa, foo(bb));
答案 1 :(得分:2)
#include <stdio.h>
int f1(void){
printf("In F1\n");
return 0;
}
int f2(void){
printf("In F2\n");
return 0;
}
int f3(void ){
printf("In F3\n");
return 0;
}
void f4(int a,int b,int c){
printf("In F4\n");
return;
}
int main(){
f4(f1(),f2(),f3());
getch();
return 0;
}
output
----------
In F3
In F2
In F1
In F4
but for
printf("%d..%d..%d",(f1(),f2(),f3()));
output
---------
In F1
In F2
In F3
0..0..0
答案 2 :(得分:0)
我认为你把两个概念混为一谈:1)参数评估的顺序(在函数调用中),以及参数推送的顺序。在第一个中,它是未指定的(依赖于实现)在传递给函数之前评估哪些订单参数。在第二个中,它取决于函数的调用约定,cdecl从右向左推送参数,几乎所有其他约定(例如,pascal)从左向右推送。
答案 3 :(得分:0)
在C ++中没有从左到右或从右到左评估的概念,这不应与运算符的从左到右和从右到左的关联性混淆:表达式f1()由于operator +的从左到右的关联性,+ f2()+ f3()被解析为(f1()+ f2())+ f3(),但是对f3的函数调用可以在第一个,最后一个或之间进行评估运行时f1()或f2()。
答案 4 :(得分:0)
在C中,参数传递机制是基于堆栈的 手段 它使用堆栈(称为:函数堆栈帧)来存储参数,因此订单是正确的,因为堆栈是LIFO。这取决于我的理解。 请看看这个链接,它会更多地解释你,我希望你可以找到一些有用的东西 http://zoo.cs.yale.edu/classes/cs427/2012a/resources/Chapter_05.pdf
第55页, 5.2.3参数传递机制
答案 5 :(得分:0)
// according to my tests: left to right for clang-3.4 and right to left
// for gcc-4.8.2
// but don't write any code relying on that: it would be highly unportable
#include <stdio.h>
int one() {
printf("1\n");
fflush(stdout);
return 1;
}
int two() {
printf("2\n");
fflush(stdout);
return 1;
}
int three() {
printf("3\n");
fflush(stdout);
return 1;
}
void test(int a, int b, int c) {
return;
}
int main() {
test(one(), two(), three());
}