C++ virtual question

Started by
9 comments, last by anis 19 years, 3 months ago
Is it always the case that regardless of compiler settings, a virtual class instance has the address to the virtual function pointer table at the same location as that of the base class? Assume MS VC.Net as the compiler. For example,

class CBase
{
public:
	CBase()
	{
		printf( "BASE construct\n" );
	}

	virtual ~CBase()
	{
		printf( "Base destroy\n" );
	}

	virtual void BaseFunc1()
	{
		printf( "BaseFunc1\n" );
	}

	virtual void BaseFunc2()
	{
		printf( "BaseFunc2\n" );
	}

	virtual void BaseFunc3()
	{
		printf( "BaseFunc3\n" );
	}


	int a;
};

void main()
{
    CBase b;
}
Will the __vfptr member variable of b be always the address of b? Happy New Year & may you guys be blessed with long life & prosperity. Anis
Advertisement
I'm not sure about your question, but THIS is true:

it is always the case (in MSVC) that, whatever the offset is to the VTable for the base class, it is always that SAME offset to the vtable for the derived classes - except where multiple inheiritance is concerned.

Basically what I'm saying is, the position of everything thing (vtable AND member data) must be fixed by the base class header file (so that all compilation units can independently agree on how to access each element). Of course this statement is only true with a given set of compiler switched, changing architectures or packing breaks binary compatibilty (and this rule of course).

I think your question is basically, is it true the the offset to the VTable is always 0 (which may be true, and in my experience seems to be true, but I'm not sure).

Even in mutliple inheiritance the above must be true, with one caveat - the above is true AFTER you cast your pointer to the appropriate class ... in class C inheirits from classes A and B ... then when you cast a C* to an A* and B* you get different addresses ... but FROM THOSE ADDRESSES, the offsets exactly match the class layout of A and B respectively.
Quote:Original post by anis
Is it always the case that regardless of compiler settings, a virtual class instance has the address to the virtual function pointer table at the same location as that of the base class? Assume MS VC.Net as the compiler.

For example,
...

Will the __vfptr member variable of b be always the address of b?

Happy New Year & may you guys be blessed with long life & prosperity.

Anis

#include <stdio.h>class CBase{public:	CBase()	{		printf( "BASE construct\n" );	}	virtual ~CBase()	{		printf( "Base destroy\n" );	}	virtual void BaseFunc1()	{		printf( "BaseFunc1\n" );	}	virtual void BaseFunc2()	{		printf( "BaseFunc2\n" );	}	virtual void BaseFunc3()	{		printf( "BaseFunc3\n" );	}	int a;};int main(int argc, char* argv[]){	CBase cb1;	printf("%p\n",&cb1);	return 0;}


I made that quick test program and I could find an instance where the __vfptr member was the same as the adress of the base class. Here is the output on my comp:

BASE construct
0012FF78
Base destroy
Press any key to continue

00422044 is the __vfptr address, obtained by setting a breakpoint on return 0, and setting a watch on cb1, which then you look at the __vfptr member listed.

I hope this helps some.

- Drew
Quote:Original post by anis
Is it always the case that regardless of compiler settings, a virtual class instance has the address to the virtual function pointer table at the same location as that of the base class?
The virtual function pointer table is not a part of the C++ language specification. It's simply an implementation technique (thus the double underscore identifier), a compiler artefact, and is not guaranteed to exist at all.

Just keep that in mind, whatever hackery you're trying to propagate.
Quote:Original post by Oluseyi
Quote:Original post by anis
Is it always the case that regardless of compiler settings, a virtual class instance has the address to the virtual function pointer table at the same location as that of the base class?
The virtual function pointer table is not a part of the C++ language specification. It's simply an implementation technique (thus the double underscore identifier), a compiler artefact, and is not guaranteed to exist at all.

Just keep that in mind, whatever hackery you're trying to propagate.


Right! This is the point. Why do you have to think about __vfptr??? You should have no access to it!!!
you have to think about it if you are trying for binary compatibility in the real world ... without thinking about it things like COM and .NET couldn't exist ...

of course when you are writing an entire program purely in C++, you simply shouldn't care ...

but when you start buying people's compnents / dlls, and having to import / export ... etc ... then you care.
To "Xai", you understood my question correctly. "Drew_Benton", I made a very similar program to find out that the address of the instance contains a pointer to a VTable. I'm thinking about VTable cos I have known about polymorphism for a while but have shunned it simply because I did not know what it compiles too. Anyway programming is just a hobby for me, one reason why I never bothered about learning the fundamentals until now. Presently I'm working on my own engine for a simple action game whereby you'll be a stick character fighting other stick figure. 3D FPS but without the guns, think along the Xiao Xiao series. Anyway, I realised that I will have to use virtual functions to simplify things. Hence my sudden interest to understand it.

On a related note, I have a question on security (OS related). Assuming a helper function of a class used by an OS is virtual, say function A(). Now, this function A() is called in a critical part of the kernel, through a public function B(). Essentially the code executing in function A() could be any instruction and the kernel trap is issued in B(). This being the case, if the VTable is modified (say through a memcpy) so that the pointer to A() points to my own function C(), will it be right to say that C() can also execute any instruction that it wants? Assume the signature of C() is same as that of A().
Quote:Original post by anis
On a related note, I have a question on security (OS related). Assuming a helper function of a class used by an OS is virtual, say function A(). Now, this function A() is called in a critical part of the kernel, through a public function B(). Essentially the code executing in function A() could be any instruction and the kernel trap is issued in B(). This being the case, if the VTable is modified (say through a memcpy) so that the pointer to A() points to my own function C(), will it be right to say that C() can also execute any instruction that it wants? Assume the signature of C() is same as that of A().


That's why you have code sections( readonly ) of your code. so that people can't write over your code. Check out the NX attribute added to newer CPU's. Furthermore, the kernal would never call a public method, they would only call their own kernal methods. That's why you don't see kernal32.dll depending on user32.dll.

Cheers
CHris
CheersChris
Quote:Original post by chollida1
...Check out the NX attribute added to newer CPU's...


Thanks. That explains it. I'm unfamiliar with workings of the security of OSes. Anyway, check http://www.theinquirer.net/?article=20352 regarding the NX attribute. I came across it @ slashdot & did a google.

Anis
Quote:Original post by Oluseyi
Quote:Original post by anis
Is it always the case that regardless of compiler settings, a virtual class instance has the address to the virtual function pointer table at the same location as that of the base class?
The virtual function pointer table is not a part of the C++ language specification. It's simply an implementation technique (thus the double underscore identifier), a compiler artefact, and is not guaranteed to exist at all.

Just keep that in mind, whatever hackery you're trying to propagate.


Although, due to COM, use of vtables and vtable layout is a defacto standard amongst COM-compliant C++ compilers.

Enigma

This topic is closed to new replies.

Advertisement