|
Hello everyone,
From MSDN virtual base class reference, what means "If a derived class overrides a virtual function that it inherits from a virtual base class, and if a constructor or a destructor for the derived base class calls that function using a pointer to the virtual base class, the compiler may introduce additional hidden "vtordisp" fields into the classes with virtual bases."
I do not understand why an additional hidden filed is needed?
http://msdn2.microsoft.com/en-us/library/wcz57btd.aspx#Mtps_DropDownFilterText
thanks in advance,
George
|
|
|
|
|
George_George wrote: http://msdn2.microsoft.com/en-us/library/wcz57btd.aspx#Mtps_DropDownFilterText
The circumstance requiring such field it is explained here http://msdn2.microsoft.com/en-us/library/7sf3txa8(VS.71).aspx[^](however I have to admit I don't fully understand the whole machanism ).
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Thanks for sharing this, CPallini!
I also do not understand this, quoted below. It is appreciated if you or other gurus could share points about what does the following paragraph mean?
http://msdn2.microsoft.com/en-us/library/7sf3txa8.aspx[^]
--------------------
The problem is that the virtual function may be passed an incorrect this pointer as a result of discrepancies between the displacements to the virtual bases of a class and the displacements to its derived classes. The solution provides a single construction displacement adjustment, called a vtordisp field, for each virtual base of a class.
--------------------
regards,
George
|
|
|
|
|
Well I think we can understand the quoted paragraph keeping in mind the memory layout drawings of the OP article. Probably whenever the memory layout is optimizied to retain only a copy of the base class stuff, you need that offset field to keep aligned, in derived classes, info about the base one (roughly speaking, the compiler says:"OK you ask to me two identical copies of the base stuff, I'll make only a single one and all will go fine if I provide you an additional field, i.e. the offset to adjust derived class pointers alignement to such single copy").
BTW it's only a guess, actually I'm not a guru and this time the matter is a bit intricate.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Thanks CPallini,
I do not quite understand what do you mean "you need that offset field to keep aligned"? Why and what needs to be aligned? Could you provide more description or some pseudo code please?
regards,
George
|
|
|
|
|
Do you remember the memory layout depicted in your OP article? That was only a schematic, neverthless it showed that mamory layout changes (with respect to ordinary derivation) whenever base class stuff is reported only once (instead of twice) in the derived one. Hence the need of an offset to rearrange things. As I stated before, it is only a guess (based on my arrogant assumptions... ).
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Thanks CPallini,
Re-arrange for what purpose? To facilitate what operations? Why if not re-arranged, it will not work for what operation?
CPallini wrote: the need of an offset to rearrange things
regards,
George
|
|
|
|
|
Somethimes an example is better than a thousand of words:
class A
{
int a;
public:
A(){a=0;}
virtual int do_things(int a){this->a = a; return 0;}
};
class AB: public A
{
int ab;
public:
AB(){ab=1;}
virtual int do_things(int a){A::do_things(a);this->ab = a+1; return 1;}
};
class AC: public A
{
int ac;
public:
AC(){ac=2;}
virtual int do_things(int a){A::do_things(a);this->ac = a+2; return 2;}
};
class ABAC: public AB, public AC
{
int abac;
public:
ABAC(){abac = 4;}
virtual int do_things(int a){AB::do_things(a);AC::do_things(a);this->abac = a+4; return 4;}
};
int main()
{
ABAC abac;
}
If you put a breakpoint at the end of main function and put abcd inside the watch window, then you'll see something like the following
- abac {abac=4 } ABAC
- AB {ab=1 } AB
- A {a=0 } A
- __vfptr 0x0041574c const ABAC::`vftable'{for `AB'} *
[0] 0x00411136 ABAC::do_things(int) *
a 0 int
ab 1 int
- AC {ac=2 } AC
- A {a=0 } A
- __vfptr 0x00415740 const ABAC::`vftable'{for `AC'} *
[0] 0x0041111d [thunk]:ABAC::do_things`adjustor{12}' (int) *
a 0 int
ac 2 int
abac 4 int
Line [0] 0x0041111d [thunk]:ABAC::do_things`adjustor{12}' (int) * shows the adjustor, i.e. the offset (equalt to 12 decimal, 0xC hex) needed to align vftable'{for `AC'} to ::`vftable'{for `AB'} (0x00415740 + 0x0000000c = 0x0041574c).
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Thanks CPallini,
Your sample looks great! I have debugged it by myself.
Two more questions about your sample,
1.
CPallini wrote: __vfptr 0x0041574c const ABAC::`vftable'{for `AB'} *
This line means the address of __vfptr pointer is 0x0041574c? Or the value of __vfptr pointer is 0x0041574c?
2.
CPallini wrote: [0] 0x00411136 ABAC::do_things(int) *
This line means the address of __vfptr[0] pointer is 0x00411136? Or the value of __vfptr[0] is 0x00411136?
regards,
George
|
|
|
|
|
As far as I can understand:
George_George wrote: This line means the address of __vfptr pointer is 0x0041574c? Or the value of __vfptr pointer is 0x0041574c?
The value of __vfptr pointer is 0x0041574c.
George_George wrote: This line means the address of __vfptr[0] pointer is 0x00411136? Or the value of __vfptr[0] is 0x00411136?
The value of __vfptr[0] is 0x00411136.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Thanks CPallini,
Great! Two more comments,
1.
I noticed that the __vfptr array in AB and in AC are different (0x0041574c and 0x00415740), means the vtable for AB and AC sub-object are different?
__vfptr 0x0041574c const ABAC::`vftable'{for `AB'} *
__vfptr 0x00415740 const ABAC::`vftable'{for `AC'} *
2.
__vfptr 0x0041574c const ABAC::`vftable'{for `AB'} *
[0] 0x00411136 ABAC::do_things(int) *
In my understanding, __vfptr is an array of function pointers. [0] is the value of the 1st function pointer in vtable, right?
So, 0x00411136 means function ABAC::do_things(int) resides in address 0x00411136?
regards,
George
|
|
|
|
|
George_George wrote: 1.
I noticed that the __vfptr array in AB and in AC are different (0x0041574c and 0x00415740), means the vtable for AB and AC sub-object are different?
Yes.
George_George wrote: In my understanding, __vfptr is an array of function pointers. [0] is the value of the 1st function pointer in vtable, right?
So, 0x00411136 means function ABAC::do_things(int) resides in address 0x00411136?
Yes.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Thanks CPallini,
I read your great reply again. Here is what I am interested and confused,
--------------------
[0] 0x0041111d [thunk]:ABAC::do_things`adjustor{12}' (int) *
--------------------
1.
I think it means at location 0x0041111d, there is a place holder function, [thunk]:ABAC::do_things, and its job is simply redirect calls the vtable entry in AB, right?
2.
--------------------
the offset (equalt to 12 decimal, 0xC hex) needed to align vftable'{for `AC'} to ::`vftable'{for `AB'} (0x00415740 + 0x0000000c = 0x0041574c).
--------------------
I am interested in the function align. Is it a MSVC built-in private function? How do you know the align rule of the align source and align destination? -- Which in this case align vftable'{for `AC'} to ::`vftable'{for `AB'}, why it does not align from something else to something else?
regards,
George
|
|
|
|
|
George_George wrote: 1.
I think it means at location 0x0041111d, there is a place holder function, [thunk]:ABAC::do_things, and its job is simply redirect calls the vtable entry in AB, right?
I think it simply contains the adjustor field, i.e. the offset to the AB vtable.
You know I'm only guessing about..., anyway, here [^] thunk is explained, though for a slightly different circumstance.
George_George wrote: 2.
--------------------
the offset (equalt to 12 decimal, 0xC hex) needed to align vftable'{for `AC'} to ::`vftable'{for `AB'} (0x00415740 + 0x0000000c = 0x0041574c).
--------------------
I am interested in the function align. Is it a MSVC built-in private function? How do you know the align rule of the align source and align destination? -- Which in this case align vftable'{for `AC'} to ::`vftable'{for `AB'}, why it does not align from something else to something else?
It is a transparent mechanism (to the programmer) to glue vtables. Since the compiler has to include A stuff once, it chooses a simple way: includes the A stuff only for the AB inheritance path (hence no need to align there) and align accordingly the AC one. Probably inner implementation details are Microsoft specific; I don't know if other C++ compilers, such as g++ allow this kind of (space) optimization and the way they eventually implement it.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Thanks CPallini,
Two more comments,
1.
CPallini wrote: I think it simply contains the adjustor field, i.e. the offset to the AB vtable.
So, the adjustor field also takes memory address? Which is at location 0x0041111d?
2.
I have studied the link, looks cool. So, after the adjust, the entry [0] for vtable for AC will be, 0x00415740 + 0x0000000c = 0x0041574c, which is address for vtable for AB.
I am wondering what compiler will do next after the adjustment? Translate 0x00415740[0] to 0x0041574c[0] for the function pointer?
regards,
George
|
|
|
|
|
George_George wrote: 1.
CPallini wrote:
I think it simply contains the adjustor field, i.e. the offset to the AB vtable.
So, the adjustor field also takes memory address? Which is at location 0x0041111d?
Yes, I suppose.
George_George wrote: 2.
I have studied the link, looks cool. So, after the adjust, the entry [0] for vtable for AC will be, 0x00415740 + 0x0000000c = 0x0041574c, which is address for vtable for AB.
I am wondering what compiler will do next after the adjustment? Translate 0x00415740[0] to 0x0041574c[0] for the function pointer?
Again yes, I suppose.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Thanks CPallini,
I read again my original question and your sample. I think we are making a big mistake.
The question about virtual base class and virtual inheritance. But in your sample below, none is about virtual inheritance. I modified the code below to make virtual inheritance.
My question is about,
--------------------
From MSDN virtual base class reference, what means "If a derived class overrides a virtual function that it inherits from a virtual base class, and if a constructor or a destructor for the derived base class calls that function using a pointer to the virtual base class, the compiler may introduce additional hidden "vtordisp" fields into the classes with virtual bases."
I do not understand why an additional hidden filed is needed?
--------------------
1.
Do you think my modification of your sample reflects the issue described above?
2.
I noticed you invoke virtual function do_things of class A, in class AB's constructor. I am confused whether it is the same scenario as mentioned in MSDN document, "a constructor or a destructor for the derived base class". Does MSDN mean calling virtual function from constructor of base class A or derived class AB? The term "the derived base class" makes me confused.
It is appreciated if you could clarify.
#include <iostream>
using namespace std;
class A
{
int a;public: A(){a=0;}
virtual int do_things(int a){this->a = a; return 0;}
};
class AB: virtual public A
{
int ab;
public:
AB(){ab=1;}
virtual int do_things(int a){A::do_things(a);this->ab = a+1; return 1;}
};
class AC: virtual public A
{
int ac;
public:
AC(){ac=2;}
virtual int do_things(int a){A::do_things(a);this->ac = a+2; return 2;}
};
class ABAC: public AB, public AC
{
int abac;
public:
ABAC(){abac = 4;}
virtual int do_things(int a){AB::do_things(a);AC::do_things(a);this->abac = a+4; return 4;}
};
int main()
{
ABAC abac;
return 0;
}
regards,
George
|
|
|
|
|
Indeed you're right: with respect thew original article, we made a big mistake .
I think the right code to show the issue is, for instance
#include <iostream>
using namespace std;
class A
{
int a;public: A(){a=0;}
virtual int do_things(int a){this->a = a; return 0;}
};
class AB: virtual public A
{
int ab;
public:
AB(){ab=1; A * pA = this; pA->do_things(1);}
virtual int do_things(int a){A::do_things(a);this->ab = a+1; return 1;}
};
class AC: virtual public A
{
int ac;
public:
AC(){ac=2; A * pA = this; pA->do_things(2);}
virtual int do_things(int a){A::do_things(a);this->ac = a+2; return 2;}
};
class ABAC: public AB, public AC
{
int abac;
public:
ABAC(){abac = 4;}
virtual int do_things(int a){AB::do_things(a);AC::do_things(a);this->abac = a+4; return 4;}
};
int main()
{
ABAC abac;
return 0;
}
that produce the following memory layout:
- abac {abac=4 } ABAC
- AB {ab=2 } AB
- A {a=2 } A
- __vfptr 0x00415700 const ABAC::`vftable' *
[0] 0x0041122b [thunk]:ABAC::do_things`vtordisp{4294967292,0}' (int) *
a 2 int
ab 2 int
- AC {ac=4 } AC
- A {a=2 } A
- __vfptr 0x00415700 const ABAC::`vftable' *
[0] 0x0041122b [thunk]:ABAC::do_things`vtordisp{4294967292,0}' (int) *
a 2 int
ac 4 int
abac 4 int
If you try to compile and run it using #pragma vtordisp(off) then you get a runtime error (hence the usefulness of vtordisp ).
Don't ask me the interpretation of vtordisp{4294967292,0} , at the moment I'm not able to... (though 4294967292 is -3, an offset?).
Perhaps the argument needs more investigation.
BTW was you [^]?
See also this one [^], it's interesting.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Thanks CPallini,
I do not need to understand the exact details about what the numeric values in vtordisp means. I only need to use why the field is needed and its usage (how compiler and runtime utilize it).
According to the links, it is described when it is used, and it also conforms to your sample above.
My question is, why the field is needed and its usage and how compiler and runtime utilize it?
--------------------
but we have to add it to classes that inherit from a virtual base class and override virtual functions just in case the user does call a virtual function in the constructor or destructor.
--------------------
BTW:
I am not the person who posted,
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2128468&SiteID=1[^]
regards,
George
|
|
|
|
|
hi
recently i have joined a company as software engineer on c++ (Embeded Systems)they are writing the code for thereself i.e they are not using ACTIVE X Controls like buttons, dialog boxes. just they are writing the code for the active x controls for their self in visual C++.i want to know how we will write the code for Active X Controls in detial.
|
|
|
|
|
You can use MFC , ATL or just plain C . CP has a lot of articles about, for instance see [^]
BTW Try also to post in the right forum, the COM [^] one.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
No problem when using VC6.
With vs2008, it compiles but not take effect.
Extended style for CListCtrl:
LVS_EX_HIDELABELS|LVS_EX_SINGLEROW
I've tried to define WINVER and _WIN32_WINNT higher as
#define WINVER 0x0600
#define _WIN32_WINNT 0x0600
but also no effect.
|
|
|
|
|
Doest this [^] help?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
|
i am 3rd-year student of university.
i ready to do project which i can do~
so i am thinking what can i make~
and i want to make USB control system.
USB control system is allowing computer to use USB that is registered by administrator.
if you want to use USB in your computer, you should input your password.
but i just have idea , and i don't know what should i do first....
My friend don't know ...
so can you please give me tip and
recommand book which i can reference?
(i can do c, c++ not winapi or MFC)
firstly, i am sorry, i am from korea.
and i am not good in wriitting english so please understand~
Thank you everyone~
|
|
|
|
|