8 Stimmen

Das C++ impliziert dies, und zwar genau so, wie es auf den Stack geschoben wird

Ich muss wissen, ob beim Aufruf einer Klassenmethode in C++ der implizite Zeiger "this" das erste oder das letzte Argument ist, d. h. ob er zuerst oder zuletzt auf den Stapel geschoben wird.

Mit anderen Worten, ich möchte wissen, ob eine Klassenmethode, die aufgerufen wird, vom Compiler als solche angesehen wird:

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

Im weiteren Sinne würde dies auch die Frage beantworten, ob G++ diesen Zeiger als letztes oder als erstes verschieben würde. Ich habe Google befragt, aber ich habe nicht viel gefunden.

Und als Randbemerkung: Wenn C++-Funktionen aufgerufen werden, tun sie dasselbe wie C-Funktionen, d. h:

push ebp
mov ebp, esp

Alles in allem: würde eine Klassenmethode, die aufgerufen wird, so aussehen?

; 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

Vielen Dank und herzlichen Dank.

EDIT: um Dinge zu klären, ich bin mit GCC/G++ 4.3

15voto

Michael Punkte 52790

Dies hängt von der Aufrufkonvention Ihres Compilers und der Zielarchitektur ab.

Standardmäßig wird Visual C++ dies nicht auf den Stack legen. Bei x86 verwendet der Compiler standardmäßig die Aufrufkonvention "thiscall" und übergibt dies im ecx-Register. Wenn Sie __stdcall für Ihre Mitgliedsfunktion angeben, wird sie als erster Parameter auf den Stack gelegt.

Bei x64 auf VC++ werden die ersten vier Parameter in Registern übergeben. Dies ist der erste Parameter und wird im Register rcx übergeben.

Raymond Chen hat vor einigen Jahren eine Serie über die Einberufung von Kongressen veröffentlicht. Hier sind die x86 y x64 Artikel.

9voto

John Millikin Punkte 190278

Dies hängt von Ihrem Compiler und Ihrer Architektur ab, aber in G++ 4.1.2 unter Linux ohne Optimierungseinstellungen behandelt es this als ersten Parameter, der in einem Register übergeben wird:

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

Disassemblierung von 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

2voto

David Claridge Punkte 5929

Ich habe mir gerade den C++-Standard (ANSI ISO IEC 14882 2003), Abschnitt 9.3.2 "Der this-Zeiger", durchgelesen, und es scheint nichts darüber zu sagen, wo er in der Liste der Argumente vorkommen sollte, also hängt es vom jeweiligen Compiler ab.

Versuchen Sie, einen Code mit gcc zu kompilieren, indem Sie das Flag '-S' verwenden, um Assembler-Code zu erzeugen, und schauen Sie sich an, was er tut.

1voto

Chris Jester-Young Punkte 212385

Diese Art von Details ist in der C++-Norm nicht vorgesehen. Lesen Sie sich jedoch die C++ ABI für gcc (und andere C++-Compiler, die der C++ ABI folgen).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X