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

原文地址:https://www.cnblogs.com/mydomain/p/1791561.html