Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are Class declarations and defintions stored in object oriented languages (C++) after compilation?

I understand how the memory is organised for C programs(the stack, heap, function calls etc). Now, I really don't understand how all these things work in Object Oriented Languages (to be more specific, C++).

I understand that whenever I use the new keyword, the space for the object is allocated onto the heap.

Some of my basic questions regarding this are:

1) Are class definitions stored somewhere in memory during execution of the program ?

2) If yes, then where and how is it stored. If no, then how are the functions dispatched at run time (in case of the virtual/non-virtual functions).

3) When an object is allocated memory, what all details about the object are stored in it ? (which class it belongs to, the member functions, the public private variables/functions etc.)

So basically, can someone please explain how the object oriented code gets converted after/during compilation so that these O.O.P. features are implemented?

I am comfortable with Java/C++. So you can explain the logic with either of the languages since both have quite distinct features.

Also, please add any reference links so that I can read it from there too, just in case some further doubts arise!

Thanks!

like image 898
jatin3893 Avatar asked Dec 08 '22 12:12

jatin3893


2 Answers

1) Are class definitions stored somewhere in memory during execution of the program ?

In C++, no. In Java, yes.

2) If yes, then where and how is it stored. If no, then how are the functions dispatched at run time (in case of the virtual/non-virtual functions).

In C++, calls to non-virtual functions are replaced by the compiler with the actual static address of the function; calls to virtual functions work through a virtual table. new is translated to memory allocation (the compiler knows the precise size) followed by a call to the (statically-determined) constructor. A field access is translated by the compiler to accessing memory in a statically-known offset from the beginning of the object.

It's similar in Java - in particular, a virtual table is used for virtual calls - except that field access can be done symbolically.

3) When an object is allocated memory, what all details about the object are stored in it ? (which class it belongs to, the member functions, the public private variables/functions etc.)

In C++ - no metadata is stored (well, with the exception of some bits needed for RTTI). In Java you get type information and visibility for all members and a few other things - you can check out the Java class file definition for more information.

So basically, can someone please explain how the object oriented code gets converted after/during compilation so that these O.O.P. features are implemented?

As you can see from my answers above, it really depends on the language.

In a language like C++, the heavy lifting is done by the compiler, and the resulting code have very little to do with object oriented concepts - in fact, the typical target language for a C++ compiler (native binary code) is untyped.

In a language like Java, the compiler targets an intermediate representation which usually contains a lot of extra details - type information, member visibility, etc. This is also what enables reflection in those sorts of languages.

like image 73
Oak Avatar answered Dec 11 '22 00:12

Oak


Are class definitions stored somewhere in memory during execution of the program ?

Definitions are not preserved - at least not in the sense of maintaining the information you have at compile time.

When an object is allocated memory, what all details about the object are stored in it ? (which class it belongs to, the member functions, the public private variables/functions etc.)

During compilation, things like references to fields are transformed into dereferences of pointers with a fixed offset. For example, the a->first might be translated as something like *(a + 4), a->second as *(a + 8) and so on. The actual numbers will depend on the sizes of the previous fields, the target architecture, etc.

Similar things apply for the size of the objects (for purposes of allocation and deallocation).

In short, the sizes of the objects and the offsets of their fields are known at compile time and they are replaced in the actual binary.

If no, then how are the functions dispatched at run time (in case of the virtual/non-virtual functions).

Things like virtual method calls are typically translated in a similar way as fields, since they too can be considered "fields" of a hidden data structure (called vtable) of that class. A pointer to the vtable of a given class is stored in every object (of that class), if it has virtual methods.

The correct implementations of non-virtual methods are known at compile time and thus these methods can be "linked" on the spot without the use of a vtable.

like image 42
Theodoros Chatzigiannakis Avatar answered Dec 11 '22 01:12

Theodoros Chatzigiannakis