Reputation: 15631
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
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?
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
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
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
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