views:

302

answers:

4

Hi: down to business:

I need to know whether, when a class method in C++ is called, the implicit 'this' pointer is the first argument, or the last. i.e: whether it is pushed onto the stack first or last.

In other words, I'm asking whether a class method, being called, is taken by the compiler to be:

int foo::bar(foo *const this, int arg1, int arg2); 
//or:
int foo::bar(int arg1, int arg2, foo *const this);

By extension therefore, and more importantly, that would also answer whether G++ would push the this pointer last or first, respectively. I interrogated google, but I didn't find much.

And as a side note, when C++ functions are called, do they do the same thing as C functions? i.e:

push ebp
mov ebp, esp

All in all: would a class method being called look like this?

; About to call foo::bar.
push dword 0xDEADBEEF
push dword 0x2BADBABE
push dword 0x2454ABCD ; This one is the this ptr for the example.
; this code example would match up if the this ptr is the first argument.
call _ZN3foo3barEpjj

Thanks, and much obliged.

EDIT: to clarify things, I'm using GCC/G++ 4.3

+14  A: 

This depends on the calling convention of your compiler and the target architecture.

By default, Visual C++ will not push this on the stack. For x86, the compiler will default to "thiscall" calling convention and will pass this in the ecx register. If you specify __stdcall for you member function, it will be pushed on the stack as the first parameter.

For x64 on VC++, the first four parameters are passed in registers. This is the first parameter and passed in the rcx register.

Raymond Chen had a series some years ago on calling conventions. Here are the x86 and x64 articles.

Michael
http://en.wikipedia.org/wiki/X86_calling_conventions
Havenard
Thanks. The article from Raymond Chen cleared it up for me. All the best.
+1  A: 

This sort of detail is not specified by the C++ standard. However, read through the C++ ABI for gcc (and other C++ compilers that follow the C++ ABI).

Chris Jester-Young
+6  A: 

This will depend on your compiler and architecture, but in G++ 4.1.2 on Linux with no optimization settings it treats this as the first parameter, passed in a register:

class A
{
public:
    void Hello(int, int) {}
};

void Hello(A *a, int, int) {}

int main()
{
    A a;
    Hello(&a, 0, 0);
    a.Hello(0, 0);
    return 0;
}

Disassembly of main():

movl $0, 8(%esp)
movl $0, 4(%esp)
leal -5(%ebp), %eax
movl %eax, (%esp)
call _Z5HelloP1Aii

movl $0, 8(%esp)
movl $0, 4(%esp)
leal -5(%ebp), %eax
movl %eax, (%esp)
call _ZN1A5HelloEii
John Millikin
Thanks. This was extremely helpful as well.
+2  A: 

I just had a read of the C++ Standard (ANSI ISO IEC 14882 2003), section 9.3.2 "The this pointer", and it does not seem to specify anything about where it should occur in the list of arguments, so it's up to the individual compiler.

Try compiling some code with gcc using the '-S' flag to generate assembly code and take a look at what it's doing.

David Claridge
It doesn't even specify whether the arguments go on the stack at all, or even if there is one stack.
MSalters