Author Topic: Pet peeve #1  (Read 16490 times)

CommonTater

  • Guest
Re: Pet peeve #1
« Reply #15 on: December 16, 2012, 07:11:34 AM »
Hi qword,

No, it is the beautiful C  :t

C with classes? You're kidding.

Gunther

You can do object oriented programmin in C (eg. COM Objects) ... but why on earth would you want to?

There's a huge difference between a struct named "Class" and an actual C++ Class ....

qWord

  • Member
  • *****
  • Posts: 1475
  • The base type of a type is the type itself
    • SmplMath macros
Re: Pet peeve #1
« Reply #16 on: December 16, 2012, 08:09:12 AM »
CommonTater ,
can you please explain a bit more detailed what you mean with "must" and "can"? I'm sure you can create a c++ class without a virtual table , unless using virtual functions (also, AFAIK the vtbl is implementation specific and not part of the standard) .

qWord
MREAL macros - when you need floating point arithmetic while assembling!

CommonTater

  • Guest
Re: Pet peeve #1
« Reply #17 on: December 16, 2012, 10:26:38 AM »
CommonTater ,
can you please explain a bit more detailed what you mean with "must" and "can"? I'm sure you can create a c++ class without a virtual table , unless using virtual functions (also, AFAIK the vtbl is implementation specific and not part of the standard) .

C++ methods are accessed by a virtual table (a struct of pointers) inside the class.  It's also the key to inheritance in classes as the new class inherits (copies) the vtable from it's parent...

The vtable is hidden from the programmer in C++ but C calls class functions as class->vtable->method() so we can see it.

Trust me, it's there... always.



qWord

  • Member
  • *****
  • Posts: 1475
  • The base type of a type is the type itself
    • SmplMath macros
Re: Pet peeve #1
« Reply #18 on: December 16, 2012, 10:40:56 AM »
C++ methods are accessed by a virtual table (a struct of pointers) inside the class.  It's also the key to inheritance in classes as the new class inherits (copies) the vtable from it's parent...
This is also my understanding of classes with virtual methods. I can't though why any compiler should add a non-virtual metode to the vtable.
MREAL macros - when you need floating point arithmetic while assembling!

qWord

  • Member
  • *****
  • Posts: 1475
  • The base type of a type is the type itself
    • SmplMath macros
Re: Pet peeve #1
« Reply #19 on: December 16, 2012, 11:34:50 AM »
let me describe my thoughts in other words:
If you create a class in C++ which does not contain virtual functions, everything the compiler needs to known (for all modules) is the structure/class definition. The methods then are simply called by their name (e.g. Class::methode@Signature) and the linker does the fix up. The other members are referenced by the corresponding structure pointer (this-pointer). Because no function pointers are used in the structure definition, derived classes must overwrite/hide the methods by redeclaring the same function (this must be supported by the language and is thus not possible with C in that way).

For classes with virtual methods, the class template get be copied and the constructor* then fix up the virtual method pointers of the base class (in the vtable). The virtual methods then can be called either by the base class or by the derived classes. The overwritten virtual methods of the base class can still be called through the template of the base class (unless the class is not abstract).
I'm right here?

regards, qWord

* if it is a derived class
MREAL macros - when you need floating point arithmetic while assembling!

CommonTater

  • Guest
Re: Pet peeve #1
« Reply #20 on: December 16, 2012, 12:34:28 PM »
C++ methods are accessed by a virtual table (a struct of pointers) inside the class.  It's also the key to inheritance in classes as the new class inherits (copies) the vtable from it's parent...
This is also my understanding of classes with virtual methods. I can't though why any compiler should add a non-virtual metode to the vtable.

The vtable is a struct of pointers to methods ... rather than have 5 identical copies of every method in memory at the same time (a la Delphi) the vtables all point to the first copy.

It has *nothing* to do with virtual vs real methods.

What is in the actual class struct itself is the class's data.

qWord

  • Member
  • *****
  • Posts: 1475
  • The base type of a type is the type itself
    • SmplMath macros
Re: Pet peeve #1
« Reply #21 on: December 16, 2012, 01:11:49 PM »
C++ methods are accessed by a virtual table (a struct of pointers) inside the class.  It's also the key to inheritance in classes as the new class inherits (copies) the vtable from it's parent...
This is also my understanding of classes with virtual methods. I can't though why any compiler should add a non-virtual metode to the vtable.

The vtable is a struct of pointers to methods ... rather than have 5 identical copies of every method in memory at the same time (a la Delphi) the vtables all point to the first copy.

It has *nothing* to do with virtual vs real methods.

What is in the actual class struct itself is the class's data.
You say: a class has always a vtable because inheritance requires it
My opinion: a vtable is only need if virtual function are used, because these requires fix up at runtime. None-virtual function are known at compile time thus they can be called by their symbol.

Anyone else can assistance?

regards qWord
MREAL macros - when you need floating point arithmetic while assembling!

CommonTater

  • Guest
Re: Pet peeve #1
« Reply #22 on: December 16, 2012, 01:35:42 PM »
let me describe my thoughts in other words:
If you create a class in C++ which does not contain virtual functions, everything the compiler needs to known (for all modules) is the structure/class definition. The methods then are simply called by their name (e.g. Class::methode@Signature) and the linker does the fix up.

Not exactly.  If it were done that way you could not replace a method in a derived class and you'd end up with multiple copies of the method code, one in each instance of the class.

In C and C++ a function's name is a pointer to the function's entry point... a variable like any other. 

When a class or object is created, these pointers are concentrated in the class's vtable.  The only place the method is called by name is in source code.

Quote
The other members are referenced by the corresponding structure pointer (this-pointer). Because no function pointers are used in the structure definition, derived classes must overwrite/hide the methods by redeclaring the same function (this must be supported by the language and is thus not possible with C in that way).

Function pointers are *hidden*... in C++ the vtable is hidden from the programmer... but a pointer to a vtable is always there.

This has nothing to do with virtual methods.

Quote
For classes with virtual methods, the class template get be copied and the constructor* then fix up the virtual method pointers of the base class (in the vtable). The virtual methods then can be called either by the base class or by the derived classes. The overwritten virtual methods of the base class can still be called through the template of the base class (unless the class is not abstract).
I'm right here?

Yes and no... You have the concept, but not the mechanics of it...

The root or base class has a pointer to a vtable (similar to an ASM jump list) that points to it's methods, including the constructor and destructor.  When an inherited (or derived) class is instantiated, it's vtable pointer simply points to it's parent's vtable... No matter how many derived classes you make, there is only one copy of the vtable and one copy of each method in memory, unless you are replacing methods.  If you overlay (replace) one or more methods in a derived class, then the derived class gets it's own copy of the vtable, with the new pointer(s) in it.

Here's what a C++ class (IExample) looks like in C...
Code: [Select]
typedef struct {
   IExampleVtbl * lpVtbl;
   DWORD          count;
   char           buffer[80];
} IExample;

C++ hides the IExamplevtbl entry from the programmer and does tricks to make it look like it has it's own copy of the parent's methods ... but the vtable is there. 

The vtable pointer is always the first entry in the struct (and thus at the same address as the struct itself). It points to a list of the addresses of the methods used in the class. If we make a second copy we can simply copy the first under a new name, call the constructor (always the first item in the Vtable) and use it with different data.

In C...
Code: [Select]
IExample test;  // declaration of an instance

test->IExampleVtbl->IExample;  // run the constructor

test->IExampleVtbl->copy(string);  // run a method

In C++...
Code: [Select]
IExample test;  // instance, constructor is run automatically

test::copy(string);

Both of the above do the same thing... it's just that in C++ it's hidden from you.


qWord

  • Member
  • *****
  • Posts: 1475
  • The base type of a type is the type itself
    • SmplMath macros
Re: Pet peeve #1
« Reply #23 on: December 16, 2012, 02:37:00 PM »
thx for your answer.
In the mean time I've done some test with VC++  and it seem like that it confirmed my assumption about the vtable that is not created for classes without virtual function. However, I will stay in tomorrow more deeply and report here.

regards, qWord
MREAL macros - when you need floating point arithmetic while assembling!

qWord

  • Member
  • *****
  • Posts: 1475
  • The base type of a type is the type itself
    • SmplMath macros
Re: Pet peeve #1
« Reply #24 on: December 17, 2012, 04:41:49 AM »
Not exactly.  If it were done that way you could not replace a method in a derived class and you'd end up with multiple copies of the method code, one in each instance of the class.
Why should the code be copied?

but a pointer to a vtable is always there.
No, it is not always there - just test it. The quick test I've made (VC++) shows that it is done that way I've described in my previous posts.
Furthermore, if you search with your favorite search engine, you will quickly find several articles and discussions that confirm my assumptions.

regards, qWord
MREAL macros - when you need floating point arithmetic while assembling!

Tedd

  • Member
  • ***
  • Posts: 377
  • Procrastinor Extraordinaire
Re: Pet peeve #1
« Reply #25 on: December 18, 2012, 01:35:08 AM »
In C++ the vtable is only required when virtual methods are present.
Some strange compilers may choose to add it in anyway, but it's not general practice.
Java, on the other hand, always has a vtable because all methods are virtual.

Code doesn't need to be copied, non-virtual methods are called directly since their address is known at compile time.
While virtual methods could have been replaced, so they must be called via a pointer - in the vtable.
The vptr is always present -- to simplify member offsets (no need to check whether there's a vtable before accessing a member) and to ensure no object can be zero bytes in length (each object must have a unique address) -- but doesn't point to a vtable if the class doesn't require one.

The usual layout for an object in memory is: { vptr, member_variables..., vtable_pointers_if_present... }
Having only a single copy of the vtable for any particular class is a possibility, but it falls down when you introduce multiple inheritance.
Potato2