Deep C++ —- virtual table

Moving further along in that ridiculously long, too many slides unneccessarily pdf Deep C, we come across Deep C++ .


#include

struct X
{
int a;
char b;
int c;

};

int main(void)
{
std:: cout << sizeof(X) << std::endl;
return 1;

}

Now that code is no different from C by much(Except for those std::cout instead of printf) and so should print out the same size as padded structs in C. (see prev post)
So it does:

 g++ cpp_vtable.cpp  -o cpp_vtable
anand@anand-usb-boot:C [master] $ gdb64 cpp_vtable
Reading symbols from /home/anand/workspace/github_stuff_public/Miscellaneous/C/cpp_vtable...(no debugging symbols found)...done.

(gdb) run
Starting program: /home/anand/workspace/github_stuff_public/Miscellaneous/C/cpp_vtable 
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000
12

Now what happens if we add a member function to that struct? Let’s see:
Am adding this line to the end of the struct.

void set_value(int v) {a = v; }

Well it still prints the same 12. What does this mean? According to the pdf, normal member functions to C++ are just syntactic sugar and are equivalent to C functions with having an additional argument in the first position as being the struct which they are a member of.

That’s why we get this output:

 g++ cpp_vtable.cpp  -o cpp_vtable
anand@anand-usb-boot:C [master] $ gdb64 cpp_vtable
Reading symbols from /home/anand/workspace/github_stuff_public/Miscellaneous/C/cpp_vtable...(no debugging symbols found)...done.
(gdb) run
Starting program: /home/anand/workspace/github_stuff_public/Miscellaneous/C/cpp_vtable 
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000
12

OK that no loadable sections found warning from gdb is weird.. but otherwise the output is the same 12 as expected.

Now let’s go ahead and make it a virtual function instead.


virtual void set_value(int v) {a = v; }

And here’s the result of compiling and running it


anand@anand-usb-boot:C [master] $ g++ cpp_vtable.cpp  -o cpp_vtable
anand@anand-usb-boot:C [master] $ gdb64 cpp_vtable

(gdb) run
Starting program: /home/anand/workspace/github_stuff_public/Miscellaneous/C/cpp_vtable 
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000
24
[Inferior 1 (process 8290) exited with code 01]
(gdb) run
Starting program: /home/anand/workspace/github_stuff_public/Miscellaneous/C/cpp_vtable 
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000

Breakpoint 1, 0x0000000000400830 in main ()

Hmm we still get the same warning, but the size has been doubled. It must be the virtual table pointer. But how do we know, it’s not allocating memory separately for a virtual functions. Time to add another func to the source code.

So here’s how the new struct looks like:

struct X
{
int a;
char b;
int c;
virtual void set_value(int v) {a = v; }
virtual int get_value(int v) {return a; }
virtual void increase_value() { a++;}

};

And here’s the output of running the program.

anand@anand-usb-boot:C [master] $ g++ cpp_vtable.cpp  -o cpp_vtable
anand@anand-usb-boot:C [master] $ gdb64 cpp_vtable
GNU gdb (GDB) 7.5.91.20130417-cvs-ubuntu

(gdb) run
Starting program: /home/anand/workspace/github_stuff_public/Miscellaneous/C/cpp_vtable 
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000
24
[Inferior 1 (process 8353) exited with code 01]
(gdb) 

You can see that the size is the same as previous code 24. So it confirms if there’s a virtual function, there’s a pointer to a virtual table created as part of the structure. Infact, this same virtual table is used for verifying that inheriting classes, ensure overriding the virtual functions.

By inductive reasoning the next step is to simply add another struct to the code and see what happens.

Here’s what happens, if i copy paste the same struct as struct Y and keep only the get_value virtual function.

anand@anand-usb-boot:C [master] $ g++ cpp_vtable.cpp  -o cpp_vtable
anand@anand-usb-boot:C [master] $ gdb64 cpp_vtable
(gdb) run
Starting program: /home/anand/workspace/github_stuff_public/Miscellaneous/C/cpp_vtable 
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000
24
24
[Inferior 1 (process 8674) exited with code 01]
(gdb) quit

Just as expected it’s the same size, and is printed as we coded. :) . So each struct really does have a separate virtual table. We have nullified the hypothesis that all structs/classes share a virtual table.

Next, test would be to see if inherited classes shared a vtable or not, but i’ll save that for some other time.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s