Re: Interview questions

From: E. Robert Tisdale (E.Robert.Tisdale_at_jpl.nasa.gov)
Date: 07/03/04


Date: Fri, 02 Jul 2004 17:42:57 -0700

Niklas Borson wrote:

> Sorry I'm slow in replying.
> I was out of time and offline for a week.
> Please do not construe my silence as agreement.

Please do not construe my silence as agreement.

> E. Robert Tisdale wrote:
>
> Here's an example:
>
> class Foo {
> public:
> virtual ~Foo(void);
> virtual void Hello(void);
> };
>
> 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

Did you just forget to show us the vtable?

> 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.

How did your compiler know where to get the entry point for Hello?

> In short, the Test function accesses the vtable directly
> without calling a wrapper function.

Does it surprise you
that the C++ compiler inline'd the wrapper function?

> According to Stroustrup, the word virtual means
> "may be redefined later in a class derived from this one".
> Nothing about wrapper functions there.

You don't show us a derived class
with a redefined "virtual" function.
How is Stroustup's remark relevant?

> 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.

I agree that it's ugly and amy invoke "undefined behavior"
as far as the ANSI/ISO C standards are concerned
but it *does* work and it ports everywhere.

> The user needs to know the order and types of the function
> pointers, which is to say *everything* about Foo_VTable.

Just as the C++ compiler knows these things
*without* any public definition of the virtual function table.

> 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.

I agree. C programmers must know enough about a Foo_VTable
to define a Bar_VTable correctly.
But neither definition should be published in a public header file.

> He may not actually *reference* that definition in the code,
> but that doesn't mean [that]
> it's hidden or encapsulated in any meaningful way.

Correct!
And that's one very good reason why C++ exists.
C just doesn't provide the protection that is required
to write reliable object oriented programs.

>>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.)

I didn't realize that.

> 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.

You probably have me confused with someone else.

> 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 [that]
> there's only one way, just that my way is valid and reasonable.
> A better way, of course, is to just use C++.)



Relevant Pages

  • Re: Interview questions
    ... The compiler has access to the definition of the Foo class. ... it knows that Hello is the second virtual function in the class so it ... I see no reason to suppose that a wrapper function ever existed. ... call mechanism and the vtables -- again, ...
    (comp.lang.cpp)
  • Re: [EGN] Hoisting Loop Invariants (Was: Re: [EGN] Numerical Accuracy)
    ... compiler out there somewhere that did as you claim. ... > the programmer has this knowledge, then the programmer should not use ... >> string in a loop, regardless of the blatant inefficiency of doing so. ...
    (comp.programming)
  • Re: The Philosophy of Programming?
    ... A compiler is free to ... >>is to allocate on entry to almost any block. ... > int foo{ ... But any programmer who wants to be more than a coder prefers, I think, ...
    (comp.programming)
  • Re: Brian Kernighan, maybe Im not worthy, maybe Im scum
    ... what experienced programmers do, ... the compiler doesn't have the free pass to /assume/ that the function ... Nobody has recommended doing all optimization by hand to my knowledge. ... Compiler behavior in optimization simply has no place in a language ...
    (comp.programming)
  • Re: Static/Strong/Implicit Typing
    ... and every programmer would instantly revere the static type analysis. ... will inform your compiler of your construction. ... the two varieties and consciously break the type disjointness. ... Common Lisp is not quite as abstract, ...
    (comp.lang.lisp)