473,839 Members | 1,380 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

tweaking the virtual function table pointer

Case:

-- class X has occupies tiny amount of memory:

sizeof(X) is only a little greater than sizeof(void*).

-- X instantiates thousands of objects and memory does matter.

-- The class has a virtual destructor, and therefore, a pointer
to a virtual function table.

-- This class, now, needs a boolean variable 'boolF' which would
cost at the very least 1 byte, which is a lot under the
circumstances described above.

--> idea: (1) copy the virtual function table at another place.

(2) let the virtual function pointer point to either
one of the virtual function tables (which are
identical), but:

The place where the pointer points to indicates the
state of the 'implicitly represented' variable
'boolF'.

Such a setup is profitable, if

N * sizeof(bool) > sizeof(virtual function table),

where N = estimated number of instantiated objects.

Does the standard impose the management of virtual function tables
strictly enough to elaborate on such a solution? Is such a
solution practical?

Thanks

Frank

Sep 23 '05 #1
7 1783
Frank-René Schäfer wrote:
[...]
Does the standard impose the management of virtual function tables
strictly enough to elaborate on such a solution? Is such a
solution practical?


The Standard says nothing about "management of virtual function tables"
since it's outside of the realm of its concern. It's an implementation
detail.

V
Sep 23 '05 #2

"Frank-René Schäfer" <fr************ **@gmx.net> wrote in message
news:11******** **************@ g49g2000cwa.goo glegroups.com.. .
Case:

-- class X has occupies tiny amount of memory:

sizeof(X) is only a little greater than sizeof(void*).

-- X instantiates thousands of objects and memory does matter.

-- The class has a virtual destructor, and therefore, a pointer
to a virtual function table.

-- This class, now, needs a boolean variable 'boolF' which would
cost at the very least 1 byte, which is a lot under the
circumstances described above.

--> idea: (1) copy the virtual function table at another place.

(2) let the virtual function pointer point to either
one of the virtual function tables (which are
identical), but:

The place where the pointer points to indicates the
state of the 'implicitly represented' variable
'boolF'.

Such a setup is profitable, if

N * sizeof(bool) > sizeof(virtual function table),

where N = estimated number of instantiated objects.

Does the standard impose the management of virtual function tables
No. The standard does not at all dictate how virtual function
behavior is implemented, only that virtual functions behave in
a particular manner. There's no requirement to use a mechanism
such as a 'vtable' (although afaik many/ most compilers do use them).
strictly enough to elaborate on such a solution? Is such a
solution practical?


That depends upon your needs, but I doubt it.

-Mike
Sep 23 '05 #3
* =?iso-8859-1?B?RnJhbmstUmV u6SBTY2jkZmVy?= :
Case:

-- class X has occupies tiny amount of memory:

sizeof(X) is only a little greater than sizeof(void*).

-- X instantiates thousands of objects and memory does matter.

-- The class has a virtual destructor, and therefore, a pointer
to a virtual function table.

-- This class, now, needs a boolean variable 'boolF' which would
cost at the very least 1 byte, which is a lot under the
circumstances described above.

--> idea: (1) copy the virtual function table at another place.

(2) let the virtual function pointer point to either
one of the virtual function tables (which are
identical), but:

The place where the pointer points to indicates the
state of the 'implicitly represented' variable
'boolF'.

Such a setup is profitable, if

N * sizeof(bool) > sizeof(virtual function table),

where N = estimated number of instantiated objects.

Does the standard impose the management of virtual function tables
strictly enough to elaborate on such a solution?

Is such a solution practical?


No, the standard does not specify whether there _is_ a vtable or not.

However, if your objects are not handled polymorphically , then simply get rid
of that virtual destructor, and you've made room for your boolean.

If on the other hand the objects are handled polymorphically you might
implement the essentials of your idea by using two classes derived from a
common base class, one representing 'false' and the other 'true'.

Another idea can be to store the booleans externally to the objects, as a
bitset. For that idea you need some way to easily associate each object with
a unique index, without more memory overhead. That of course depends on your
objects.

And a third idea, to use the flyweight pattern, in essence to store pure data
objects and bring the functionality to the data (or vice versa, depending on
your point of view) when required.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Sep 23 '05 #4
Frank-René Schäfer wrote:
Case:

-- class X has occupies tiny amount of memory:

sizeof(X) is only a little greater than sizeof(void*).

-- X instantiates thousands of objects and memory does matter.

-- The class has a virtual destructor, and therefore, a pointer
to a virtual function table.

-- This class, now, needs a boolean variable 'boolF' which would
cost at the very least 1 byte, which is a lot under the
circumstances described above.

--> idea: (1) copy the virtual function table at another place.

(2) let the virtual function pointer point to either
one of the virtual function tables (which are
identical), but:

The place where the pointer points to indicates the
state of the 'implicitly represented' variable
'boolF'.

Such a setup is profitable, if

N * sizeof(bool) > sizeof(virtual function table),

where N = estimated number of instantiated objects.

Does the standard impose the management of virtual function tables
strictly enough to elaborate on such a solution? Is such a
solution practical?

Thanks

Frank


Flyweight (mentioned by A.Steinbach) is a good solution.

Is there any reason why you actually need these objects instantiated
simultaneously? I mean if you had (say) a vector<char> v, you could
create a temporary

myfn(ExpensiveC har(v[i]))

That is, only create the object when you need it, and store it
efficiently when you don't.

Calum
Sep 23 '05 #5
Actually, I was considering this 'design' as a kind of 'flyweight'
pattern,
where the key is the pointer to the vtable.

-- What about the typeid()-operator? Considering your second proposal,
with twol classes, let's say "X_false", the other "X_true". How
could I
turn the switch for an existing object, i.e. that it's virtual
pointer points
to it's counterpart?

Objects of type X_false and X_true will have the same size and
structure,
but is it sure, that if the tweaking works, that the deallocation is
handled
100% propperly?

Sep 23 '05 #6
* =?iso-8859-1?B?RnJhbmstUmV u6SBTY2jkZmVy?= :
Actually, I was considering this 'design' as a kind of 'flyweight'
pattern,
It isn't. See the posting by Calum Grant in this thread. Or, google. ;-)

where the key is the pointer to the vtable.

-- What about the typeid()-operator?
It reports the dynamic type of an object, which with your proposed solution
would vary.

Considering your second proposal,
with twol classes, let's say "X_false", the other "X_true". How
could I turn the switch for an existing object, i.e. that it's
virtual pointer points to it's counterpart?
The implementation I sketched assumed, without mention, that the boolean would
be constant for each object. However, with only polymorphic usage you can do
dirty tricks. Not that I recommend this, and I'm not even sure whether it's
well-defined or perhaps undefined behavior, and since you're counting _bytes_
this solution requires a really efficient small object allocator (otherwise
you can easily have, say, 24 bytes "invisible" overhead per object):

#include <iostream>
#include <stdexcept>
#include <memory>

class Data {};
class SomeInterface{ public: virtual ~SomeInterface( ) {} };

class Base: public SomeInterface
{
public:
virtual bool boolValue() const = 0;
virtual void setBoolValue( bool newValue ) = 0;

Base& operator=( Base const& other )
{
myData = other.myData; // Could be optimized.
setBoolValue( other.boolValue () );
}

static Base* Base::instanceA t( void* storage, Data const& data, bool
aBoolValue );
static std::auto_ptr<B ase> newInstance( Data const& data, bool aBoolValue
);

private:
class DerivedFalse; friend class DerivedFalse;
class DerivedTrue; friend class DerivedTrue;

Data myData;

Base( Data const& data ): myData( data ) {};
Base( Base const& ); // None.
};

class Base::DerivedFa lse: public Base
{
public:
DerivedFalse( Data const& data ): Base( data ) {}
virtual bool boolValue() const { return false; }
virtual void setBoolValue( bool newValue );
};

class Base::DerivedTr ue: public Base
{
public:
DerivedTrue( Data const& data ): Base( data ) {}
virtual bool boolValue() const { return true; }
virtual void setBoolValue( bool newValue );
};

Base* Base::instanceA t( void* storage, Data const& data, bool aBoolValue )
{
if( aBoolValue )
{
return new( storage ) DerivedTrue( data );
}
else
{
return new( storage ) DerivedFalse( data );
}
}

std::auto_ptr<B ase> Base::newInstan ce( Data const& data, bool aBoolValue )
{
// ASSERT sizeof(Base) == sizeof(Base::De rivedFalse)
// ASSERT sizeof(Base) == sizeof(Base::De rivedTrue)
return std::auto_ptr<B ase>(
instanceAt( new char[sizeof(Base)], data, aBoolValue )
);
}

void Base::DerivedFa lse::setBoolVal ue( bool newValue )
{
if( newValue != boolValue() )
{
Data data = myData;
this->~DerivedFalse( );
new( this ) DerivedTrue( data );
}
}

void Base::DerivedTr ue::setBoolValu e( bool newValue )
{
if( newValue != boolValue() )
{
Data data = myData;
this->~DerivedTrue() ;
new( this ) DerivedFalse( data );
}
}

int main()
{
try
{
std::auto_ptr<B ase> p( Base::newInstan ce( Data(), true ) );

std::cout << sizeof( Base ) << std::endl;
std::cout << std::boolalpha;

std::cout << p->boolValue() << std::endl;
p->setBoolValue ( false );
std::cout << p->boolValue() << std::endl;
p->setBoolValue ( true );
std::cout << p->boolValue() << std::endl;
}
catch( std::exception const& x )
{
std::cerr << "!" << x.what() << std::endl;
}
}

Objects of type X_false and X_true will have the same size and
structure, but is it sure, that if the tweaking works, that the
deallocation is handled 100% propperly?


I think so.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Sep 23 '05 #7
* Alf P. Steinbach:
std::auto_ptr<B ase> Base::newInstan ce( Data const& data, bool aBoolValue )
{
// ASSERT sizeof(Base) == sizeof(Base::De rivedFalse)
// ASSERT sizeof(Base) == sizeof(Base::De rivedTrue)
return std::auto_ptr<B ase>(
instanceAt( new char[sizeof(Base)], data, aBoolValue )
);
}


Forgot to fix that before posting, t'was just a raw hack. But I think you get
the idea in spite of that formally very incorrect code -- the problem with
this code is allocation as char array and deallocation as Base object, which
is Not Good (TM). That must be fixed for real code.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Sep 23 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

15
19351
by: Prabu | last post by:
Hi, I'm new to python, so excuse me if i'm asking something dumb. Does python provide a mechanism to implement virtual functions? Can you please give a code snippet also...:) Thanx in advance -Prabu.
4
4431
by: vijay | last post by:
I have a doubt with size of classed with virtual functions I have declared A,A1,A2 ,B , C, D some classes with no varaibles but a vitual function each, The size of A is as expected 4 bytes with one vtbl ptr BUt when I derive the class B from class A (both have 1 virtual function each ) the size remains still as 4 bytes . class A = 4 bytes class B :public A = 4 bytes class...
4
2725
by: DaKoadMunky | last post by:
I was recently looking at some assembly code generated by my compiler. When examining the assembly code associated with constructors I noticed that the dynamic-dispatch mechanism was enabled before member initialization but after base initialization. To speak in implementation details the virtual function table pointer for objects being constructed was set before member initialization but after base initialization. Curiousity then...
6
3499
by: pakis | last post by:
I am having a problem of pure virtual function call in my project. Can anyone explaine me the causes of pure virtual function calls other than calling a virtual function in base class? Thanks
8
3257
by: siddhu | last post by:
Like other virtual functions does the entry of virtual destructor exist in VTABLE?
12
2113
by: mohan | last post by:
Hi All, How to implement virtual concept in c. TIA Mohan
9
2431
by: ypjofficial | last post by:
Hello All, I am defining a class with one virtual function and storing its first 4 bytes ie. the address of the virtual function table to a file.I am again rereading the file in the same program and calling the virtual function.The function gets called nicely but it shows the junk values for the member variables of the class of which the function is a member..below is the code //Program start #include "iostream.h"
17
3558
by: Jess | last post by:
Hello, If I have a class that has virtual but non-pure declarations, like class A{ virtual void f(); }; Then is A still an abstract class? Do I have to have "virtual void f() = 0;" instead? I think declaring a function as "=0" is the same
7
2915
by: Christopher Pisz | last post by:
My problem is my derived class is getting called twice instead of the base and then the derived. I thought this was the purpose for virtuals and dynamic casting :/ I want my base class to have its method called and then the derived class have its method called. What am I not understanding? Int the following code, my Event Tester class is getting called twice for keyboard events when I step through the debugger:...
0
9855
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9697
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10908
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10587
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10649
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10295
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7829
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5682
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
4064
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.