Cl [source. cpp]/d1reportsingleclasslayout [classname]
Compilation options
Example: CL test. CPP/d1reportsingleclasslayoutderived
Note that, during inheritance, a strange all-zero field may appear: vtordisp for vbase ..
The following is an explanation of direct connection from blog Garden: http://www.cnblogs.com/fanzhidongyzby/archive/2013/01/14/2860015.html
What does vtordisp know?
I believe many people have seen this article mostly from curiosity about "vtordisp" in the title. In fact, this keyword was accidentally found when I recently checked the object model. I am a person who likes to explore the root cause of the problem (a little cool). So when I first discovered vtordisp, I naturally imported it into Google to search for relevant information, but I am not satisfied with the results. However, even so, I will sort out the relevant materials as follows and share them with you based on my understanding. I hope to learn and make progress together.
First, start with the example that generates the "vtordisp" problem.
Class base
{
Public:
Int base;
Virtual void fun (){}
};
Class der: virtual public Base
{
Int der;
Public:
Der (){}
Virtual void fun (){}
};
Der object model:
1> class der size (20 ):
1> + ---
1> 0 | {vbptr}
1> 4 | der
1> + ---
1> 8 | (vtordisp for vbase)
1> + --- (virtual base Base)
1> 12 | {vfptr}
1> 16 | base
1> + ---
1>
1> Der: $ vbtable @:
1> 0 | 0
1> 1 | 12 (Derd (Der + 0) Base)
1>
1> Der: $ vftable @:
1> |-12
1> 0 | & (vtordisp) Der: fun
1>
1> Der: fun this adjustor: 12
1>
1> VBI: Class offset O. vbptr O. vbte fvtordisp
1> Base 12 0 4 1
We found that the 8-byte offset of the object uses four bytes to store the vtordisp of the virtual Base class. In my previous blog, we did not cover this content. First, I will refer to the vtordisp's MSDN explanation. MSDN provides the following explanation:In virtual inheritance, the derived class overrides the virtual function of the base class and calls the function using the pointer of the base class in the constructor or destructor, the compiler adds the vtordisp field to the virtual base class..
However, after VS2010 testing, we found that the above sample code will generate the vtordisp field! The condition is.
1. The derived class overrides the virtual function of the virtual base class.
2. The derived class defines the constructor or destructor.
These two conditions are indispensable. This conclusion is consistent with the description here.
However, so far, we have determined the conditions for generating vtordisp. We still have no idea why it exists in an object model and how it is used (possibly explained!
This field is related to the compilation option/vd according to the data content on the front. /Vd is called constructor replacement (I am not sure what it means !), It solves the following problems:Because there is a difference between the replacement of the virtual base of the class and the replacement of its derived class, the incorrect this pointer may be passed to the virtual function. This solution provides a single structure replacement adjustment called the vtordisp field to each virtual base of the class.. However, to construct a test case that produces an incorrect this pointer, the author will not be able to give it easily. I also hope that the experts in this article will give it as a test case.
In addition, the compiler provides pre-compiled commands to disable the generation of the vtordisp field.
# Pragma vtordisp ({on | off })
In the previous section of the Code, we disabled the generation of this field. It turns out that there will be no expected errors. This is indeed incredible, the comment in another blog in the garden also expresses the same meaning. More importantly, this pre-compiled command will always be canceled in future VC versions, but I still see it under VS2010. Finally, I found some other clues in an article describing the C ++ agent. According to its description, this field is always stored as 0. To prove this conjecture, we use Der to construct an object der and view the memory content of the object.
According to the object model, the location of the vtordisp object is indeed 0.
I have encountered a virtual inherited instance. During object initialization, The vtordisp field is modified, however, vtordisp is subtracted from a constant before the initialization ends so that the final result is 0. No assembly command is displayed to access this field! (Since it is not accessible, why does it waste instructions to set its value ?) Therefore, I am also skeptical about the rationality of the compiler design vtordisp.
In any case, we find that we know little about the vtordisp field generated by the compiler. Relying solely on code actions, it is very feasible to guess the meaning of the field. It is hoped that garden friends who have a clear understanding of this content can give a reasonable explanation.