为什么函数参数的顺序颠倒了?

kra*_*mir 10 c++ function

我一直在尝试使用函数,我发现参数的顺序在内存中是相反的.这是为什么?

堆栈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)

编辑:不重复:评估顺序可能与内存布局不同,所以这是一个不同的问题.

Chr*_*phe 9

此行为是特定于实现的.

在你的情况下,这是因为参数被推入堆栈.这是一篇有趣的文章,展示了流程的典型内存布局,展示了堆栈如何发展.因此,在堆栈上推送的第一个参数将具有最高地址.


Che*_*Alf 8

调用约定取决于实现.

但是为了支持C变量函数(在...形式参数列表中用椭圆表示的C++ 中),通常按从右到左的顺序推送参数,或者为它们保留堆栈空间.这通常称为(1)C调用约定.使用这种约定,以及机器堆栈在内存中向下增长的常见约定,第一个参数应该以最低地址结束,与结果相反.

当我使用MinGW g ++ 5.1(64位)编译程序时,我得到了

000000000023FE30 000000000023FE38 000000000023FE40
Run Code Online (Sandbox Code Playgroud)

当我用32位Visual C++ 2015编译你的程序时,我得到了

00BFFC5C 00BFFC60 00BFFC64
Run Code Online (Sandbox Code Playgroud)

并且这两个结果都与C调用约定一致,与您的结果相反.

所以结论似乎是你的编译器默认不是C调用约定,至少对于非可变函数.

您可以通过...在正式参数列表的末尾添加a来测试它.


1) C调用约定还包括调用函数在函数返回时调整堆栈指针,但这与此无关.