Objective
This article traces the assembly code of the function call by observing the memory layout of the object. The layout of C + + object memory, the execution mode of virtual function, virtual inheritance, and so on are analyzed.
Writing this article stems from a post I saw on the forum. Some people asked VC use which way to achieve virtual inheritance. I wrote a little bit of code to verify it, and it turned out to be more complicated than I thought. So I simply carefully put the relevant issues all over again, and record the cost of the text.
My knowledge of the C + + object model comes mainly from the Lippman book "Inside the C + + object", in the Chinese version of the "Deep Exploration of C + + object Model", the Chinese and English version I have read, but I still recommend the Chinese version, because the translation version is really good, and Hou Jie added a lot of pictures, and fixed some errors in the original.
The compiler I am using is VC7.1, and the code in this article is validated on the VC7.1. If you run under other compilers, you need to make the appropriate adjustments, even for VC7.0 and VC6. The assembly code produced by different compilers is not the same, and it is not surprising that the code generated in the compilation code on different compilers is different from what I have listed. If you want to verify the code on the other compilers, make the appropriate changes yourself.
In addition, I found that VC7.1 's approach to implementing virtual inheritance is different from the approach used by Lippman in the book, but there was no VC7.1 at the time. Interestingly, Lippman was working at Disney when he wrote the book, and it was supposed to be about rendering software related to three-dimensional films. And now that he has come to Microsoft, I believe it should be the leading VC7.1 compiler design work. Also worth mentioning is Herb, who is a member of the C + + standards Committee, wrote too much of the classic C + + books, and now has joined Microsoft. Although I am not Microsoft's "fan", but for VC have to pay attention. The beta version of VC8.0 has also come out.
In the following text you can see many of the assembly code listed, some obviously inefficient. This may be because I did not open the compiler's tuning switch. When you turn on the tuning switch and set different optimization options, the compiler may produce much more efficient assembly code. Interested friends can try their own, and the text listed in the assembly code to do a comparison.
To facilitate the analysis and observation of the object's memory layout, I set the struct Member alignment option to 1 bytes when code was generated, and the default is 8 bytes. If you are compiling the code in your own project, please do the same setup. Because I wrote some functions. Print layout information in an object, and if the object option is not 1 bytes, running the code will cause a pointer exception error.
The code listed in this article can be downloaded from the attachment. The semantics and parameter descriptions of the macros used by the code, and a simple description of each class in the code can be found in the appendix.
Memory layout for normal class objects
First we start with the memory layout of the normal class object. C000 is an empty class, defined as follows:
struct C000
{
};
Run the following code to print its size and the contents of the object.
Print_size_detail (C000)
The results are:
The size of C000 is 1
The detail of C000 is CC