Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is order of function arguments reversed?

Tags:

c++

function

I've been experimenting a little bit with functions and I've found that the order of arguments is reversed in memory. Why is that?

stack-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;
}

CLang:

$ clang++ stack-test.cpp && ./a.out
0x7fffb9bb816c 0x7fffb9bb8168 0x7fffb9bb8164
3 1

GCC:

$ g++ stack-test.cpp && ./a.out
0x7ffe0b983b3c 0x7ffe0b983b38 0x7ffe0b983b34
3 1

EDIT: Not duplicate: Order of evaluation can be different from memory layout, so it's a different question.

like image 687
kravemir Avatar asked Jun 28 '15 13:06

kravemir


2 Answers

The calling convention depends on the implementation.

But in order to support C variadic functions (in C++ expressed with ... ellipse in the formal argument list) arguments are usually pushed, or stack space is reserved for them, in order from right to left. This is usually called (1)C calling convention. With this convention, and the common convention that the machine stack grows downward in memory, the first argument should end up at lowest address, opposite of your result.

And when I compile your program with MinGW g++ 5.1, which is 64-bit, I get

000000000023FE30 000000000023FE38 000000000023FE40

And when I compile your program with 32-bit Visual C++ 2015, I get

00BFFC5C 00BFFC60 00BFFC64

And both of those results are consistent with the C calling convention, contrary to your result.

So the conclusion appears to be that your compiler defaults to something else than C calling convention, at least for non-variadic functions.

You might test this by adding a ... at the end of the formal argument list.


1) The C calling convention also includes that it's the caller that adjusts the stack pointer when the function returns, but that's irrelevant here.

like image 179
Cheers and hth. - Alf Avatar answered Sep 23 '22 10:09

Cheers and hth. - Alf


This behaviour is implementation specific.

In your case, it's because the arguments are pushed on the stack. Here an interesting article which shows the typical memory layout of a process, which shows how the stack grows down. The first argument that is pushed on the stack will hence have the highest address.

like image 29
Christophe Avatar answered Sep 25 '22 10:09

Christophe