Re: Interview questions
From: Niklas Borson (niklasb_at_microsoft.com)
Date: 07/03/04
- Next message: Chris Gordon-Smith: "Re: Request for Code Review"
- Previous message: Default User: "Re: Where can I get a copy of the ANSI/ISO C++ Standard?"
- Next in thread: E. Robert Tisdale: "Re: Interview questions"
- Reply: E. Robert Tisdale: "Re: Interview questions"
- Maybe reply: tom_usenet: "Re: Interview questions"
- Maybe reply: tom_usenet: "Re: Interview questions"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 2 Jul 2004 15:19:32 -0700
Sorry I'm slow in replying. I was out of time and offline for a week.
Please do not construe my silence as agreement.
"E. Robert Tisdale" <E.Robert.Tisdale@jpl.nasa.gov> wrote in message news:<cbhpjb$3fp$1@nntp1.jpl.nasa.gov>...
> Niklas Borson wrote:
> > E. Robert Tisdale wrote:
> >>The user should *not* call the functions out of the vtable directly
> >>but implement *virtual* functions in foo.c or bar.c that do so.
> >
> > If I understand correctly, you're saying [that]
> > the users of the class should call a wrapper function
> > which in turn calls the actual function
> > through the pointer in the vtable.
> > Yes, one could do this.
>
> What I am saying is that this is what your C++ compiler does for you.
Maybe your compiler does this, but not mine. Here's an example:
class Foo {
public:
virtual ~Foo();
virtual void Hello();
};
void Test(Foo* foo)
{
foo->Hello();
}
And here's the assembly code my compiler generates for Test:
?Test@@YAXPAVFoo@@@Z PROC NEAR
mov ecx, DWORD PTR _foo$[esp-4]
mov eax, DWORD PTR [ecx]
jmp DWORD PTR [eax+4]
?Test@@YAXPAVFoo@@@Z ENDP
The first instruction loads the foo parameter into a register.
The second instruction loads the vtable pointer into a different
register. The third instruction performs a tail call by jumping
to the entry point of the Hello function, which it gets directly
from the vtable.
In short, the Test function accesses the vtable directly without
calling a wrapper function.
> A virtual function is actually a wrapper
> (that's why it's called a virtual function) that calls
> the actual function through the corresponding function pointer
> in the virtual function table.
According to Stroustrup, the word virtual means "may be redefined
later in a class derived from this one". Nothing about wrapper
functions there.
> > Personally,
> > I don't see the advantage of this extra function call.
> > IMO, exposing the structure of the vtable
> > does not violate encapsulation.
>
> > It doesn't expose the class's data, for example.
> > It tells you only what virtual functions the class has --
> > i.e., its interface.
>
> No!
> It is an implementation detail.
It's an implementation detail of the virtual call mechanism.
That's not the same thing as exposing the representation or
inner workings of the class.
> Siemel Naran used an array
> to represent the virtual function table.
Which did not work very well because (1) all the function
pointers had to have the same type, and (2) the call site
had to specify the array index of the virtual function
rather than its name.
> > Moreover, anyone who wants to derive from the class
> > needs to know the structure of the vtable anyway so
> > as to provide a compatible vtable for the derived class.
>
> That's because the C computer programming language
> does *not* support inheritance.
>
> Yes, the application programmer (user) must know the *order*
> in which function pointers appear in struct Foo_VTable
The user needs to know the order and types of the function
pointers, which is to say *everything* about Foo_VTable.
> but the application programmer does *not* need the definition
> of struct Foo_VTable to define struct Bar_VTable.
The implementor of Bar_VTable needs to ensure that it has
the same members in the same order as Foo_VTable. Therefore
he needs access to the definition of Foo_VTable, or
equivalent documentation.
He may not actually *reference* that definition in the code,
but that doesn't mean it's hidden or encapsulated in any
meaningful way.
> The structure of a C++ vtable isn't defined
> in *any* public C++ header [file].
It is implied by the class definition, which is typically in
a header file. That is, the compiler can deduce the vtable
layout from the class definition, though *how* it does so
(or whether there's a vtable at all) is implementation
dependant.
See the example assembler output I gave earlier. To generate
the object code for the Test function, the compiler relied on
its knowledge of the vtable layout for Foo, which it inferred
from the class definition.
> I don't see any reason why it should be defined
> in any public C header file.
> What is happening here is that the C programmer
> is playing the role of a C++ compiler in simulating inheritance.
Exactly. The programmer is playing the role of the compiler.
Therefore, things like vtables and virtual calls, which a C++
compiler creates for you, must be coded explicitly in C.
> The C programmer can and should infer
> the structure of the virtual function table from the definition
> of class Foo (struct Foo + virtual function declarations).
What virtual function declarations? There is no such thing in C.
In C++ the compiler determines the vtable layout (or whatever)
based on the virtual function declarations. In C, the programmer
must determine the vtable layout. A vtable structure seems like
a natural and obvious way of doing so.
Yes you could use wrapper functions to make the virtual function
calls, but this is not what a typical C++ compiler does. Moreover,
since implementors of derived classes still need to know both the
virtual call mechanism and the vtable layout for the base class,
hiding the actual declaration of the vtable does not actually
buy you anything in terms of encapsulation.
> Run-time polymorphism has been discussed at length
> in the comp.lang.c newsgroup. See Google Groups
>
> http://groups.google.com/
>
> and search for
>
> Tisdale Shape group:comp.lang.c.*
I did. Perhaps you didn't notice that you and I both participated
in that thread. (I posted under a different email address then, but
used my real name then and now.) At the time, you argued that it's
impossible to do OOP in C because it's not really OO unless you use
specific language features, e.g., keywords like class and virtual.
I argued to the contrary. Now you appear to have changed your tune,
and our quibble is over merely *how* one might implement virtual
functions in C. (Of course, I'm not saying there's only one way,
just that my way is valid and reasonable. A better way, of course,
is to just use C++.)
- Next message: Chris Gordon-Smith: "Re: Request for Code Review"
- Previous message: Default User: "Re: Where can I get a copy of the ANSI/ISO C++ Standard?"
- Next in thread: E. Robert Tisdale: "Re: Interview questions"
- Reply: E. Robert Tisdale: "Re: Interview questions"
- Maybe reply: tom_usenet: "Re: Interview questions"
- Maybe reply: tom_usenet: "Re: Interview questions"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|