scdmb
scdmb

Reputation: 15631

How does member function knows that it is called for specific object?

There is such C++ code:

#include <iostream>

class MojaKlasa{
public:
  int z;
  void fun(){ std::cout << this;};
};

int main()
{
  MojaKlasa a;
  a.z = 2;
  a.fun();
  return 0;
}

And coresponding assembly code:

    .file   "prog50.cpp"
    .local  _ZStL8__ioinit
    .comm   _ZStL8__ioinit,1,1
    .section    .text._ZN9MojaKlasa3funEv,"axG",@progbits,_ZN9MojaKlasa3funEv,comdat
    .align 2
    .weak   _ZN9MojaKlasa3funEv
    .type   _ZN9MojaKlasa3funEv, @function
_ZN9MojaKlasa3funEv:
.LFB957:
    .cfi_startproc
    .cfi_personality 0x0,__gxx_personality_v0
    pushl   %ebp
    .cfi_def_cfa_offset 8
    movl    %esp, %ebp
    .cfi_offset 5, -8
    .cfi_def_cfa_register 5
    subl    $24, %esp
    movl    8(%ebp), %eax
    movl    %eax, 4(%esp)
    movl    $_ZSt4cout, (%esp)
    call    _ZNSolsEPKv
    leave
    ret
    .cfi_endproc
.LFE957:
    .size   _ZN9MojaKlasa3funEv, .-_ZN9MojaKlasa3funEv
    .text
.globl main
    .type   main, @function
main:
.LFB958:
    .cfi_startproc
    .cfi_personality 0x0,__gxx_personality_v0
    pushl   %ebp
    .cfi_def_cfa_offset 8
    movl    %esp, %ebp
    .cfi_offset 5, -8
    .cfi_def_cfa_register 5
    andl    $-16, %esp
    subl    $32, %esp
    movl    $2, 28(%esp)     # a.z = 2;
    leal    28(%esp), %eax
    movl    %eax, (%esp)
    call    _ZN9MojaKlasa3funEv   # a.fun();
    movl    $0, %eax
    leave
    ret
    .cfi_endproc
.LFE958:
    .size   main, .-main
    .type   _Z41__static_initialization_and_destruction_0ii, @function
_Z41__static_initialization_and_destruction_0ii:
.LFB960:
    .cfi_startproc
    .cfi_personality 0x0,__gxx_personality_v0
    pushl   %ebp
    .cfi_def_cfa_offset 8
    movl    %esp, %ebp
    .cfi_offset 5, -8
    .cfi_def_cfa_register 5
    subl    $24, %esp
    cmpl    $1, 8(%ebp)
    jne .L7
    cmpl    $65535, 12(%ebp)
    jne .L7
    movl    $_ZStL8__ioinit, (%esp)
    call    _ZNSt8ios_base4InitC1Ev
    movl    $_ZNSt8ios_base4InitD1Ev, %eax
    movl    $__dso_handle, 8(%esp)
    movl    $_ZStL8__ioinit, 4(%esp)
    movl    %eax, (%esp)
    call    __cxa_atexit
.L7:
    leave
    ret
    .cfi_endproc
.LFE960:
    .size   _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
    .type   _GLOBAL__I_main, @function
_GLOBAL__I_main:
.LFB961:
    .cfi_startproc
    .cfi_personality 0x0,__gxx_personality_v0
    pushl   %ebp
    .cfi_def_cfa_offset 8
    movl    %esp, %ebp
    .cfi_offset 5, -8
    .cfi_def_cfa_register 5
    subl    $24, %esp
    movl    $65535, 4(%esp)
    movl    $1, (%esp)
    call    _Z41__static_initialization_and_destruction_0ii
    leave
    ret
    .cfi_endproc
.LFE961:
    .size   _GLOBAL__I_main, .-_GLOBAL__I_main
    .section    .ctors,"aw",@progbits
    .align 4
    .long   _GLOBAL__I_main
    .weakref    _ZL20__gthrw_pthread_oncePiPFvvE,pthread_once
    .weakref    _ZL27__gthrw_pthread_getspecificj,pthread_getspecific
    .weakref    _ZL27__gthrw_pthread_setspecificjPKv,pthread_setspecific
    .weakref    _ZL22__gthrw_pthread_createPmPK14pthread_attr_tPFPvS3_ES3_,pthread_create
    .weakref    _ZL20__gthrw_pthread_joinmPPv,pthread_join
    .weakref    _ZL21__gthrw_pthread_equalmm,pthread_equal
    .weakref    _ZL20__gthrw_pthread_selfv,pthread_self
    .weakref    _ZL22__gthrw_pthread_detachm,pthread_detach
    .weakref    _ZL22__gthrw_pthread_cancelm,pthread_cancel
    .weakref    _ZL19__gthrw_sched_yieldv,sched_yield
    .weakref    _ZL26__gthrw_pthread_mutex_lockP15pthread_mutex_t,pthread_mutex_lock
    .weakref    _ZL29__gthrw_pthread_mutex_trylockP15pthread_mutex_t,pthread_mutex_trylock
    .weakref    _ZL31__gthrw_pthread_mutex_timedlockP15pthread_mutex_tPK8timespec,pthread_mutex_timedlock
    .weakref    _ZL28__gthrw_pthread_mutex_unlockP15pthread_mutex_t,pthread_mutex_unlock
    .weakref    _ZL26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t,pthread_mutex_init
    .weakref    _ZL29__gthrw_pthread_mutex_destroyP15pthread_mutex_t,pthread_mutex_destroy
    .weakref    _ZL30__gthrw_pthread_cond_broadcastP14pthread_cond_t,pthread_cond_broadcast
    .weakref    _ZL27__gthrw_pthread_cond_signalP14pthread_cond_t,pthread_cond_signal
    .weakref    _ZL25__gthrw_pthread_cond_waitP14pthread_cond_tP15pthread_mutex_t,pthread_cond_wait
    .weakref    _ZL30__gthrw_pthread_cond_timedwaitP14pthread_cond_tP15pthread_mutex_tPK8timespec,pthread_cond_timedwait
    .weakref    _ZL28__gthrw_pthread_cond_destroyP14pthread_cond_t,pthread_cond_destroy
    .weakref    _ZL26__gthrw_pthread_key_createPjPFvPvE,pthread_key_create
    .weakref    _ZL26__gthrw_pthread_key_deletej,pthread_key_delete
    .weakref    _ZL30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t,pthread_mutexattr_init
    .weakref    _ZL33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti,pthread_mutexattr_settype
    .weakref    _ZL33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t,pthread_mutexattr_destroy
    .ident  "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
    .section    .note.GNU-stack,"",@progbits
  1. It seems that function fun() of class MojaKlasa is translated as normal regular function. How does function knows that it is called for specific object for example a.fun() -> call fun() for object a?

  2. Second question is, where are default constructor and destructor for class MojaKlasa? It is said that C++ automatically creates constructors and destructors for class, but it doesn't seem that one of them is included in assembly code.

Upvotes: 3

Views: 1050

Answers (3)

Paul Manta
Paul Manta

Reputation: 31597

In short, a member function has a hidden parameter:

void Class::func(int i); // Becomes...
void func(Class const* this, int i);

When you call the function, obj.func(7), it is 'converted' to func(&obj, 7). That's pretty much the jist of it.

In C++, that is a hidden/implicit parameter, but there are some languages that require this to be an explicit parameter. In Python, for example, you would have to write this (self in Python is the equivalent to this in C++):

class Class:
    def func(self, i):
        ...

Upvotes: 0

FailedDev
FailedDev

Reputation: 26940

Without looking at the assembly code at all, you should know that member functions have a hidden parameter passed. This is called the this pointer. Therefore the call has its own this pointer and each function is called specifically for that object.

Regarding your second question, you can be assured that the default constructor and destructor are generated, although without having expert knowledge of the innards of gcc compiler it can really be hard to find out where or how it is called.

I tried this with Visual Studio 2010 and I could also not find this information in the dissasembly.

Upvotes: 1

Alok Save
Alok Save

Reputation: 206606

How does function knows that it is called for specific object for example a.fun() -> call fun() for object a?

An pointer to the object this is implicitly passed to the member function as first hidden parameter.

where are default constructor and destructor for class MojaKlasa?

C++ principle is: You pay for only what you use.
Unless your code explicitly needs a default no argument constructor, the compiler would'nt generate it.

Upvotes: 7

Related Questions