Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

class

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.

like image 627
scdmb Avatar asked Aug 07 '26 13:08

scdmb


2 Answers

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.

like image 152
Alok Save Avatar answered Aug 10 '26 16:08

Alok Save


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.

like image 26
FailedDev Avatar answered Aug 10 '26 14:08

FailedDev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!