2009-08-18 4 views
6

Muszę wiedzieć, czy po wywołaniu metody klasy w C++, niejawny "ten" wskaźnik jest pierwszym lub ostatnim argumentem. tj. czy jest on najpierw lub na siłę popychany na stosie.C++ domyślnie to, i dokładnie jak to jest pchane na stosie

Innymi słowy, pytam, czy metoda klasy, nazywany jest podjęta przez kompilator jako:

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

Przez rozszerzenie zatem, a co ważniejsze, które również odpowiedzieć, czy g ++ byłoby najpierw naciśnij ten wskaźnik jako ostatni lub pierwszy. Przesłuchałem google, ale nie znalazłem zbyt wiele.

A jak na marginesie, gdy wywoływane są funkcje C++, czy robią to samo, co funkcje C? tj .:

push ebp 
mov ebp, esp 

Podsumowując: czy metoda klasy nazywa się tak?

; 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 

Dzięki, i bardzo zobowiązany.

EDIT: wyjaśnienie rzeczy, używam GCC/G ++ 4.3

+0

Byłoby szybciej, gdybyś nie zadawał tego pytania i po prostu patrzył na zestaw generowany przez Twój kompilator. Wszystkie mają przełączniki do wyjściowego kodu zespołu jako tekst. –

Odpowiedz

15

To zależy od konwencji wywołującego swojego kompilatora oraz architektury docelowej.

Domyślnie Visual C++ nie przesuwa tego na stos. W przypadku x86 kompilator domyślnie wywoła konwencję "thiscall" i przekaże ją do rejestru ekx. Jeśli podasz funkcję __stdcall dla ciebie, zostanie ona umieszczona na stosie jako pierwszy parametr.

Dla x64 na VC++ pierwsze cztery parametry są przekazywane w rejestrach. Jest to pierwszy parametr i przekazany w rejestrze rcx.

Raymond Chen miał serię kilka lat temu na temat zwoływania konwencji. Oto artykuły o numerach: x86 i x64.

+0

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

+0

Dzięki. Artykuł Raymonda Chen wyjaśnił mi to. Wszystkiego najlepszego. –

1

Ten rodzaj szczegółów nie jest określony przez standard C++. Jednak przeczytaj C++ ABI dla gcc (i innych kompilatorów C++, które śledzą C++ ABI).

8

To zależy od kompilatora i architektury, ale w g ++ 4.1.2 na Linux bez ustawień optymalizacji Traktuje this jako pierwszy parametr, przeszły w rejestrze:

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

demontaż 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

Dzięki.To też było bardzo pomocne. –

2

miałem tylko do odczytu w C++ standard (ISO IEC 14882 ANSI 2003), rozdział 9.3.2 „wskaźnik this”, i nie wydaje się, aby określić coś na temat, gdzie powinien pojawić się w lista argumentów, więc to zależy od konkretnego kompilatora.

Spróbuj skompilować kod za pomocą gcc, używając flagi "-S", aby wygenerować kod zespołu i sprawdzić, co robi.

+2

Nie określa nawet, czy wszystkie argumenty trafiają na stos, czy nawet jeden stos. – MSalters