When debugging the following code in VS 2008. I think the vtable of object
instance z should contain 2 sub-vtables for IFoo and IGoo, the sub-vtable for
IFoo should contain func/foo and the sub-vtable for IGoo should contain
func/goo), but why actually it only contains 2 sub-vtable, and each of them
has only one function item func?
[Code]
class IBase
{
public:
virtual void func() = 0;
};
class IFoo : IBase
{
public:
virtual void foo() { cout << "IFoo : IBase" << endl; }
};
class IGoo : IBase
{
public:
virtual void goo() { cout << "IGoo : IBase" << endl; }
};
class Zoo : IFoo, IGoo
{
public:
virtual void func() {cout << "Zoo : IBase" << endl; }
};
int main()
{
Zoo z;
return 0;
}
[/Code]
thanks in advance,
George
I don't know for sure, but my guess is that because the inheritance is
non-public the derived classes IFoo and IGoo don't have to provide the
vtable portion of IBase. Try to use public inheritance (note that MIDL
does not need the keyword "public" when you specify interface
inheritance, but C++ does!)
Regards,
Stuart
I am totally confused. Maybe because of my bad description. I am writing
pure C++ code, no IDL/COM/MIDL this time. :-)
> I don't know for sure, but my guess is that because the inheritance is
> non-public the derived classes IFoo and IGoo don't have to provide the
> vtable portion of IBase.
I have tried to make inheritance public, but still the same result. Here is
my code. Any ideas? Do you think whether foo and goo should be in vtable?
class IBase
{
public:
virtual void func() = 0;
};
class IFoo : public IBase
{
public:
virtual void foo() { cout << "IFoo : IBase" << endl; }
};
class IGoo : public IBase
{
public:
virtual void goo() { cout << "IGoo : IBase" << endl; }
};
class Zoo : public IFoo, public IGoo
{
public:
virtual void func() {cout << "Zoo : IBase" << endl; }
};
int main()
{
Zoo z;
return 0;
}
regards,
George
void main() {
Zoo *p = new Zoo;
p->func();
p->foo();
p->goo();
p->test();
}
Check the disaessmbly, It is-
p->func();
00411D9D mov eax,dword ptr [p]
00411DA0 mov edx,dword ptr [eax]
00411DA2 mov esi,esp
00411DA4 mov ecx,dword ptr [p]
00411DA7 mov eax,dword ptr [edx]
00411DA9 call eax
00411DAB cmp esi,esp
00411DAD call @ILT+485(__RTC_CheckEsp) (4111EAh)
p->foo();
00411DB2 mov eax,dword ptr [p]
00411DB5 mov edx,dword ptr [eax]
00411DB7 mov esi,esp
00411DB9 mov ecx,dword ptr [p]
00411DBC mov eax,dword ptr [edx+4]
00411DBF call eax
00411DC1 cmp esi,esp
00411DC3 call @ILT+485(__RTC_CheckEsp) (4111EAh)
p->goo();
00411DC8 mov ecx,dword ptr [p]
00411DCB add ecx,4
00411DCE mov eax,dword ptr [p]
00411DD1 mov edx,dword ptr [eax+4]
00411DD4 mov esi,esp
00411DD6 mov eax,dword ptr [edx+4]
00411DD9 call eax
00411DDB cmp esi,esp
00411DDD call @ILT+485(__RTC_CheckEsp) (4111EAh)
p->test();
00411DE2 mov ecx,dword ptr [p]
00411DE5 call Zoo::test (4112A8h)
It clearly show that first 3 call are through vtable.
Regards,
Manish Agarwal
"George" <Geo...@discussions.microsoft.com> wrote in message
news:6F1545AF-E2B7-45BB...@microsoft.com...
Glad you could reproduce this issue. I learned from assembly language
pattern, we can distinguish between function call from virtual table and
function call from non-virtual table.
My question is, for example the assembly code for p->func() below, why there
is two call statement?
00411D9D mov eax,dword ptr [p]
00411DA0 mov edx,dword ptr [eax]
00411DA2 mov esi,esp
00411DA4 mov ecx,dword ptr [p]
00411DA7 mov eax,dword ptr [edx]
00411DA9 call eax
00411DAB cmp esi,esp
00411DAD call @ILT+485(__RTC_CheckEsp) (4111EAh)
regards,
George
Regards,
Manish Agarwal
"George" <Geo...@discussions.microsoft.com> wrote in message
news:49FCECAE-17D1-4F69...@microsoft.com...
The 2nd call is __RTC_CheckEsp, just in case you haven't noticed.
Something related to runtime stack validation.
--PA
Two more comments,
1.
In the code below, why there are 3 times of indirection (indirection I mean
get the content pointed to by something, like indirect content access in
C/C++ using pointer), means p-->eax-->edx-->eax, how vtable is organized in
such way... :-)
00411D9D mov eax,dword ptr [p]
00411DA0 mov edx,dword ptr [eax]
00411DA2 mov esi,esp
00411DA4 mov ecx,dword ptr [p]
00411DA7 mov eax,dword ptr [edx]
00411DA9 call eax
2.
Why we need to call mov ecx,dword ptr [p], I find it is not very useful here.
regards,
George
Two more comments,
1.
In the code below, why there are 3 times of indirection (indirection I mean
get the content pointed to by something, like indirect content access in
C/C++ using pointer), means p-->eax-->edx-->eax, how vtable is organized in
such way... :-)
00411D9D mov eax,dword ptr [p]
00411DA0 mov edx,dword ptr [eax]
00411DA2 mov esi,esp
00411DA4 mov ecx,dword ptr [p]
00411DA7 mov eax,dword ptr [edx]
00411DA9 call eax
2.
There's one vtable per class, it's not embedded into each instance.
Instead, each instance contains a pointer to its class' vtable, usually
at the beginning (at offset 0).
> 00411D9D mov eax,dword ptr [p]
eax holds the address of the object, read from variable p.
> 00411DA0 mov edx,dword ptr [eax]
This reads the first four bytes from the memory pointed to by eax, that
is, the first field inside the object instance. That would be the vtable
pointer, now stored in edx
> 00411DA2 mov esi,esp
> 00411DA4 mov ecx,dword ptr [p]
Just like in the first statement, ecx now stores an address of the
object - in other words, the 'this' pointer. In __thiscall calling
convention, 'this' pointer is passed on ecx.
> 00411DA7 mov eax,dword ptr [edx]
eax now holds the first slot from vtable (pointed to by edx).
> 00411DA9 call eax
And this calls the function whose address was in the first vtable slot.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
Your reply is so clear! :-)
I understand why I am confused before, I explain what I though before.
> 00411D9D mov eax,dword ptr [p]
- p holds the address of the object (since p is declared as pointer to a new
instance variable of type Zoo);
- [] operator on p will do like what operator * (value of the variable
pointed by a pointer) will do in C/C++, which will make eax contains first
four bytes from the memory block which the actual instance variable holds.
What is the root wrong understanding of my above comments? :-)
regards,
George
These square brackets in asm syntax do not mean same as in C.
But basically yes, this statement uses variable p as a pointer,
and gets a DWORD from it into eax.
--PA
I am confused.
1. Statement mov eax,dword ptr [p] will retrieve the value of variable p
directly into eax;
2. But statement mov edx,dword ptr [eax] will retrive the value pointed by
the eax pointer.
[] has two different semantics? In my understanding, in asm [A] means
retrieve the value pointed by A, not retrieve A directly (as in item 1). Any
ideas or comments?
regards,
George
> I am confused.
There are several asm syntax flavors, the VS disassembler
uses one of them.
All these are more or less confusing. Don't worry, read the manual...
--pa
In assembly, "p" doesn't refer to the value of variable p but to the
location where this variable is stored. Essentially, p in assembly means
the same as &p would in C++.
IIRC, ecx holds the "this" pointer when calling a non-static member
function. See __thiscall for more.
These articles may help you decipher assembly:
http://www.microsoft.com/msj/0298/hood0298.aspx
http://www.microsoft.com/msj/0698/hood0698.aspx
If you get any deeper into how the compiler implements vtbls and whatnot,
see:
http://www.openrce.org/articles/files/jangrayhood.pdf
The last one used to be on MSDN, but I can't find it right now.
--
Doug Harrison
Visual C++ MVP
As we mentioned it may be a debugger issue which makes us not easy to find
which functions are in vtable. We also find how to identify whether a
function is a virtual function by looking at the assembly code.
Are there any easier and straight-forward ways to check what are the content
of a vtable for a class?
regards,
George
And statement "mov esi,esp" is just a regular assembly statement which is
used to save stack pointer before a (virtual function call in this case)
function call? No special usage here?
regards,
George
Yes, it's for that CheckEsp call:
mov esi,esp
...
cmp esi,esp
call __RTC_CheckEsp
It checks that the called function has correctly popped its parameters
from the stack.
Allow me to offer a bit of stylistic advice. In Windows, don't name your
concrete classes IXxxx. That initial capital I implies that it is an
interface -- an abstract base class. What you have there are NOT abstract
base classes.
Success is all about establishing good habits.
--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.
I am interested in the following assembly codes.
> 00411DA2 mov esi,esp
> 00411DA9 call eax
> 00411DAB cmp esi,esp
> 00411DAD call @ILT+485(__RTC_CheckEsp) (4111EAh)
I understand the process is -- esi is used to save esp before function call
to virtual function, and after the function returns esp should be restored
exactly the same and the function __RTC_CheckEsp is used to checck whether
esi and esp are the same?
What I am not sure whether esp should be expected to be exactly the same as
esi or some other rules expected?
regards,
George
I agree.
regards,
George
<rant intensity="100%">
Actually, it's a shame that MSDN doesn't list it. I just cannot
understand their policy about articles. Articles like this one by
Jan Gray are pure gold. People hunt them all over the internet,
from Google cache and what not. While MSDN site removes them.
<rant intensity="100%">
Actually, it's a shame that MSDN doesn't list it. I just cannot
understand their policy about articles. Articles like this one by
Jan Gray are pure gold. People hunt them all over the internet,
from Google cache and whatnot. While MSDN site removes them.
At the same time they retain some VB2.0 workarounds for Windows
3.11, which don't make any sense nowadays. I remember there were
other articles like Jan Gray's one that explained common
programming patterns useful with Windows (like using C++ classes
to encapsulate window procedure etc.). All these articles are
silently gone over the last 5 years.
I won't say a word about MSDN search. Because it's beyond any
decent words.
</rant>
Alex
> <rant intensity="100%">
> Actually, it's a shame that MSDN doesn't list it. I just cannot
> understand their policy about articles. Articles like this one by
> Jan Gray are pure gold. People hunt them all over the internet,
> from Google cache and whatnot. While MSDN site removes them.
>
> At the same time they retain some VB2.0 workarounds for Windows
> 3.11, which don't make any sense nowadays.
I heard that there are still Cobol projects in production and its hard
to get specialist out of retirement. So I guess someone in the MSDN
team is still maintaining (or knows someone who is maintaining) some
VB2 code on Win3x and wants online documentation whereever he
fixes that code and ...
> I won't say a word about MSDN search. Because it's beyond any
> decent words.
... he knows how to google "site:msdn.microsoft.com legacy" ;-)
> </rant>
--
SvenC
--pa
I don't hold any grudges against legacy technologies. They can
keep every article from 80's, too, for what I care. But I do care
about MS specific info that cannot be retrieved from elsewhere
except from MS itself. Like C++ implementation under the hood, or
other Windows specific in-depths topics that Rymond Chen, Larry
Osterman et al cover in their blogs. I hate spending hours by
assembling puzzles from blog entries, kilometers of comments and
tons of Usenet posts in order to figure out how MS C++ compiler
handles virtual tables, for example. This information must be in
MSDN library for every version of the compiler.
For every major VS release they should pick someone from the C++
compiler team and make him/her to write an article like Jan Gray
did. Or update existing one if it doesn't reflect the curent
version of the compiler.
Alex
I don't think they are going to dump C++. MS does a lot to improve
its C++ compiler and VC++ as a whole. But using MSDN library
becomes more and more difficult. This is ridiculous that I need to
use other search engines to find things in MSDN instead of MSDN
search.
Alex
> "SvenC" wrote:
>> I heard that there are still Cobol projects in production and
>> its hard to get specialist out of retirement.
>
> I don't hold any grudges against legacy technologies. They can
> keep every article from 80's, too, for what I care. But I do care
> about MS specific info that cannot be retrieved from elsewhere
> except from MS itself...
I was only ironically ranting along with you. That's why I quoted
<rant>...</rant>. Next time I add ;-)
> I hate spending hours by assembling puzzles from blog entries,
> kilometers of comments and tons of Usenet posts in order to
> figure out how ... [works]. This information must be in
> MSDN library for every version of the compiler.
Absolutely - so much stuff written somewhere, so hard to find
the full picture when you need it. But that brings us back to the
search engine of the locally installed MSDN library. It feels slow
and blind compared to web search engines. One excuse is the
lack of a ranking system for an optimized index which google
has by analyzing how often links are referenced elsewhere. I still
hope that MSDN online with its community features will help
here but it depends on people voting and commenting...
Nevertheless, some ideas integrated into the newer libraries like
Filters and "Sort by" options can help to get the right content
into the top 20 list. Its just that we are so pampered with google
results that anything less is bad experience.
BTW: one default in the local MSDN library annoys me: full
text search uses OR as default operator between word. Go to
Tools->Options->Help->General and unselect "Include partial
matches in local search results". That at least stops the default
result of 500 hits.
> For every major VS release they should pick someone from
> the C++ compiler team and make him/her to write an article
> like Jan Gray did. Or update existing one if it doesn't reflect
> the curent version of the compiler.
That would be a perfect world. But wait, when the compiler
team has to document what they do I hear the moaning that it
takes so long to get bug fixes and new features introduced ;-)
He who is without sin among you, let him throw the first stone.
--
SvenC
Yes. I noticed recently that MSDN online results in the search
pane are more relevant. Probably they use some ranking for
articles.
> BTW: one default in the local MSDN library annoys me: full text
> search uses OR as default operator between word. Go to
> Tools->Options->Help->General and unselect "Include partial
> matches in local search results". That at least stops the
> default result of 500 hits.
Oh, thanks for that! You can't imagine how much aggravation it
caused.
> That would be a perfect world. But wait, when the compiler team
> has to document what they do I hear the moaning that it takes so
> long to get bug fixes and new features introduced ;-)
But they find time and resources to make Channel9 videos, post
blog entries and participate in Usenet discussions occasionally.
So, why not to take this knowledge to the place where it belongs?
If developers feel that they don't have time to write full blown
MSDN article about a topic, then they could e-mail the link to
their blog entry or Usenet answer to those who responsible for
MSDN content. Technical writers would pick it up from there and
reformat articles according to MSDN standards.
Alex
>> That would be a perfect world. But wait, when the compiler team
>> has to document what they do I hear the moaning that it takes so
>> long to get bug fixes and new features introduced ;-)
>
> But they find time and resources to make Channel9 videos, post
> blog entries and participate in Usenet discussions occasionally.
> So, why not to take this knowledge to the place where it belongs?
> If developers feel that they don't have time to write full blown
> MSDN article about a topic, then they could e-mail the link to
> their blog entry or Usenet answer to those who responsible for
> MSDN content. Technical writers would pick it up from there and
> reformat articles according to MSDN standards.
That sounds reasonable.
Tock, tock - anybody from Microsoft MSDN listening for
valuable suggestions?
--
SvenC
My question is, are there any convenient ways to find for a specific class,
how many functions are in vtable, and what are the functions?
regards.
George
What practical purpose would be aided by knowing this? Doesn't
matter if you're writing a textbook or a bot, I recommend you drop
this line of inquiry.
Nathan Mates
--
<*> Nathan Mates - personal webpage http://www.visi.com/~nathan/
# Programmer at Pandemic Studios -- http://www.pandemicstudios.com/
# NOT speaking for Pandemic Studios. "Care not what the neighbors
# think. What are the facts, and to how many decimal places?" -R.A. Heinlein
> My question is, are there any convenient ways to find for a specific
> class, how many functions are in vtable, and what are the functions?
I doubt that information is available in C++ and I never needed that
information for the apps I designed and implemented.
I would expect that the number of entries should be available but
not in a portable way. You have to know implementation details of
the compiler you use. So what does it buy you?
Whenever you think you need that information to solve a problem
you are likely using a wrong class design.
--
SvenC
My purpose is, in a complex inheritance relationship components design, if I
could know the entries (address of function to be called), I can figure out
and debug more efficiently which function will be called, so I need such
information.
But if you think if VC does not provide such information, it is also fine. :-)
regards,
George
> My purpose is, in a complex inheritance relationship components
> design, if I could know the entries (address of function to be
> called), I can figure out and debug more efficiently which function
> will be called, so I need such information.
A good rule of thumb is to use only programming techniques which
you (believe to have) fully understood. If you need to use the
debugger so early and heavily you probably should go with an
easier design.
So learn how the different inheritance and template class designs
work and only after you understood that think about using them.
But beware of thinking too complex and using too complex class
relationships. Another general rule of thumb: easier is better.
> But if you think if VC does not provide such information, it is also
> fine. :-)
One way to learn/verify how inheritance works is by creating *small*
samples which focus just on the point you want to understand and
print out some text to let you see the program flow.
So if you have virtual functions in a class hierarchie just put a
std::cout << "theCurrentClassName::theFuncName" << std::endl;
in each function and use it in a console app.
Just go with the assumption that VC's implementation of C++
inheritance is correct then you do not need to debug the vtables
but just use inheritance as it is described in lots of books.
If there was a bug in the VC implementation of inheritance that
could only be a seldom corner case as it would have been
reported already. Here I get back to thumb rules: finding a corner
case in such a basic C++ thing like inheritance does make me think
that the design which uses that corner case is not easy enough and
not well understood enough. So go for another design.
--
SvenC
regards,
George
Only if it comes with a warning "For debugging purposes only. These details
will change in the next release of the compiler." And then people will
still ignore it and complain when their programs which have undefined
behavior according to the C++ standard stop working.
Is "or debugging purposes only" you mean some Visual Studio compiler/linker
error messages? I never seen them before. :-)
regards,
George
first: please learn how to quote so that each individual post makes
sense when read alone.
second: please try harder to read and understand answers.
I try to show you both points in this example:
[first: I quote what you answered]
>>> ... I do care
>>> about MS specific info that cannot be retrieved from elsewhere
>>> except from MS itself. Like C++ implementation under the hood, or
>>> other Windows specific in-depths topics that Rymond Chen, Larry
>>> Osterman et al cover in their blogs. ... This information must be in
>>> MSDN library for every version of the compiler.
>>
>> Only if it comes with a warning "For debugging purposes only. These
>> details will change in the next release of the compiler." And then
>> people will still ignore it and complain when their programs which
>> have undefined behavior according to the C++ standard stop working.
>>
> Is "or debugging purposes only" you mean some Visual Studio
> compiler/linker error messages? I never seen them before. :-)
Now try to see how Ben answered on Alex sentence. Read Alex last
sentence "This information must be..."
That sentence was answered or commented by Ben. So it is the MSDN
library which should be tagged on topics when something in that topic
might change in a future version.
This kind of warning would be extremely helpful to you as you tend to
try understanding useless details which most other people accept as
implementation detail and avoid depending on them as good as one can.
But even those warnings are or would be nothing than written content
and that does only help when you try your best to read and understand
that content.
I don't know how to say it more clearly: try harder to understand what
is important and neglect what is unimportant.
--
SvenC
I just did a search in MSDN for "debugging purposes only". There is actually
no API document marked with this information. If it is from MSDN library,
could you show some links which contain such information please?
regards and have a good weekend,
George
> I just did a search in MSDN for "debugging purposes only". There is
> actually no API document marked with this information. If it is from
> MSDN library, could you show some links which contain such
> information please?
OK, you decided that quoting is irrelevant.
Learn about "subjunctive" and "supposition" and read Ben's post again.
In this case it goes like:
If A decides to do X, A should also do Y.
If X is not done, Y is irrelevant.
A = MSDN writers
X = add implementation details and internal details
Y = add the comment "for debugging purposes only"
--
SvenC
I understand your logics now. But actually I can not find any stuff like for
debugging purpose only MSDN.
According to your logics, could you show me some pages which contains things
like "for debugging purposes only" please?
> I understand your logics now. But actually I can not find any stuff
> like for debugging purpose only MSDN.
>
> According to your logics, could you show me some pages which contains
> things like "for debugging purposes only" please?
I give up. When you start asking technically relevant questions and I
may be of help with those questions I'll try to answer but this makes
no sense to me.
--
SvenC
Alex suggested that the information "should" be there. It is not. "should
be" and "already is" are very different.
I suggest that in fact the information should NOT be there because people
would misuse it.
You are so kind! :-)
regards,
George
I should say sorry to you, and it is totally my English understanding issue.
I was born in Asia and the language is quite different. :-)
Sorry again!
regards,
George