我一直在尝试使用函数,我发现参数的顺序在内存中是相反的.这是为什么?
堆栈TEST.CPP:
#include <stdio.h>
void test( int a, int b, int c ) {
printf("%p %p %p\n", &a, &b, &c);
printf("%d %d\n", *(&b - 1), *(&b + 1) );
}
int main() {
test(1,2,3);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
铛:
$ clang++ stack-test.cpp && ./a.out
0x7fffb9bb816c 0x7fffb9bb8168 0x7fffb9bb8164
3 1
Run Code Online (Sandbox Code Playgroud)
GCC:
$ g++ stack-test.cpp && ./a.out
0x7ffe0b983b3c 0x7ffe0b983b38 0x7ffe0b983b34
3 1
Run Code Online (Sandbox Code Playgroud)
编辑:不重复:评估顺序可能与内存布局不同,所以这是一个不同的问题.
调用约定取决于实现.
但是为了支持C变量函数(在...形式参数列表中用椭圆表示的C++ 中),通常按从右到左的顺序推送参数,或者为它们保留堆栈空间.这通常称为(1)C调用约定.使用这种约定,以及机器堆栈在内存中向下增长的常见约定,第一个参数应该以最低地址结束,与结果相反.
当我使用MinGW g ++ 5.1(64位)编译程序时,我得到了
Run Code Online (Sandbox Code Playgroud)000000000023FE30 000000000023FE38 000000000023FE40
当我用32位Visual C++ 2015编译你的程序时,我得到了
Run Code Online (Sandbox Code Playgroud)00BFFC5C 00BFFC60 00BFFC64
并且这两个结果都与C调用约定一致,与您的结果相反.
所以结论似乎是你的编译器默认不是C调用约定,至少对于非可变函数.
您可以通过...在正式参数列表的末尾添加a来测试它.
1) C调用约定还包括调用函数在函数返回时调整堆栈指针,但这与此无关.