2009-08-18 11 views
6

Ho bisogno di sapere se, quando viene chiamato un metodo di classe in C++, il puntatore implicito 'questo' è il primo argomento, o l'ultimo. cioè: se è stato messo in pila prima o dopo.Il C++ implicito questo, e esattamente come viene inserito nello stack

In altre parole, mi sto chiedendo se un metodo di classe, chiamato, è preso dal compilatore di essere:

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

Per estensione, pertanto, e ancora più importante, che sarebbe anche rispondere se G ++ sarebbe spingere il puntatore per ultimo o per primo, rispettivamente. Ho interrogato google, ma non ho trovato molto.

E come nota a margine, quando vengono chiamate le funzioni C++, fanno la stessa cosa delle funzioni C? Ad esempio:

push ebp 
mov ebp, esp 

Tutto sommato: un metodo di classe si chiamerebbe simile a questo?

; 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 

Grazie, e molto obbligato.

EDIT: per chiarire le cose, sto usando GCC/G ++ 4.3

+0

Sarebbe stato più veloce per voi non porre questa domanda e osservare l'assembly generato dal compilatore. Hanno tutti gli switch per generare il codice assembly come testo. –

risposta

15

Ciò dipende dalla convenzione di chiamata del compilatore e l'architettura di destinazione.

Per impostazione predefinita, Visual C++ non lo invierà nello stack. Per x86, il compilatore utilizzerà automaticamente la convenzione di chiamata "thiscall" e lo passerà nel registro di ecx. Se si specifica __stdcall per la funzione membro, verrà inserito nello stack come primo parametro.

Per x64 su VC++, i primi quattro parametri vengono passati nei registri. Questo è il primo parametro e passato nel registro rcx.

Raymond Chen aveva una serie alcuni anni fa sulla chiamata di convenzioni. Ecco gli articoli x86 e x64.

+0

http://en.wikipedia.org/wiki/X86_calling_conventions – Havenard

+0

Grazie. L'articolo di Raymond Chen lo ha chiarito per me. Ti auguro il meglio. –

1

Questo tipo di dettaglio non è specificato dallo standard C++. Tuttavia, leggi lo C++ ABI per gcc (e altri compilatori C++ che seguono l'ABI C++).

8

Questo dipenderà dal compilatore e l'architettura, ma in G ++ 4.1.2 su Linux senza impostazioni di ottimizzazione essa tratta this come primo parametro, passati in un registro:

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

Smontaggio di 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 
+0

Grazie.Questo è stato estremamente utile pure. –

2

ho appena avuto una lettura del ++ standard C (ANSI ISO IEC 14882 2003), capitolo 9.3.2 "il questo puntatore", e non sembra per specificare nulla dove dovrebbe avvenire nel elenco di argomenti, quindi è compito del singolo compilatore.

Prova a compilare del codice con gcc utilizzando il flag '-S' per generare codice assembly e dare un'occhiata a ciò che sta facendo.

+2

Non specifica nemmeno se gli argomenti vanno in pila, o anche se c'è uno stack. – MSalters