4、对变量在栈上存储顺序,及函数返回值与参数在栈上存放顺序的思考(2)
2)接下来,我们将讨论第二个问题,那就是函数返回值与参数在栈上存放顺序。
我们设计如下程序:
#include "iostream"
using namespace std;
int test(int a, int b){
int c;
printf("%p\n",&b); //最后一个参数
printf("%p\n",&a); //第一个参数
printf("%p\n",&c); //函数的返回值地址
return c;
}
int main()
{
int a = 1;
int b = 2;
int (*f)(int, int);
f = test;
int t = f(a, b);
cout << &a <<endl
<< &b <<endl;
printf("%p\n",test);
}
在GCC上结果如下所示:
在VS下执行结果如下所示:
由上可以,确实最后一个参数是先入栈的。至于c的地址就是函数的返回地址,我是参考文章[1],网友jixingzhong如此说。我们在汇编语言中学过,函数的返回地址是将要执行的下一条指令的地址;这里的意思是,把调用函数的指令的下一条指令入栈,以便调用完函数后返回,而我觉得参考文章中jixingzhong理解错这句了,所以我认为是错的。
在本程序中,test函数的返回地址应当是
int t = f(a, b);
cout << &a <<endl
的汇编指令后,在执行完函数后下一条将要执行的指令的地址。
网友Arthur_认为,通过如下程序可以求得这个地址:
#include "iostream"
using namespace std;
int* test(int a, int b){
int c;
printf("%p\n",&b); //最后一个参数
printf("%p\n",&a); //第一个参数
printf("%p\n",&c); //函数的返回值地址
return ((int*)&b-1);
}
int main()
{
int a = 1;
int b = 2;
int* (*f)(int, int);
f = test;
int *t = f(a, b);
cout << &a <<endl
<< &b <<endl;
printf("%p\n",t);
}
而很明显的,这个结果是a的地址。所以,我认为,网友Arthur的想法也是不正确的(欢迎争鸣)。而正确的结论就当是本文中,我用红色标明的地方。
当然,我希望了解这方面知识的高手们一起来讨论一下这个问题。
参考:
[1] http://topic.csdn.net/t/20060901/14/4991970.html