473,714 Members | 2,552 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

same overhead in calling virtual and non virtual member function...?

Hello All,

So far I have been reading that in case of a polymorphic class ( having
at least one virtual function in it), the virtual function call get
resolved at run time and during that the vtable pointer is made use
of..

eg.
class one
{
virtual void fun1(){ cout<<"one::fun 1";} //This is a virtual
function.
void fun2(){ cout<<"one ::fun2";}//Not a virtual function.

};

int main()
{
one * o = new one;
o->fun1();
o->fun2();
delete o;
o= NULL;
return 0;
}

so when the virtual function gets called through the base class poitner
the call actually gets expanded to the code like this
o->vfptr[0]();
My confusion is how the call to the non virtual function (here fun2
)gets resolved in polymorphic class?
When does the compiler decide to look into the vtable and when not to
look?
As in this scenario I strongly feel that, every time the compiler has
to look into the vtable irrespective of the virtuality or non
virtuality of the function.If it finds the function entry in the vtable
then it calls the function from there otherwise if it doesn't find any
entry into the vtable it looks for the non virtual function and then
execute the fuction code?
So in other words whenever your class is polymorphic , we have to deal
with this overhead always whether the class user calls the virtual or
non virtual function...

Can anyone please clarify it..?

Thanks and Regards,
Yogesh Joshi
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]

Sep 8 '06 #1
11 3438
yp*********@ind iatimes.com wrote:
So in other words whenever your class is polymorphic , we have to deal
with this overhead always whether the class user calls the virtual or
non virtual function...

Can anyone please clarify it..?
The C++ standard does not specify a "vtable". However with most C++
compiler implementations , virtual functions are resolved by looking into
the vtable and non virtual functions are called directly (as if you
called a non-member function) regardless of whether the class is
polymorphic. The overhead of looking into the vtable is either
minuscule or irrelevant on modern day CPU's and certainly not something
you should concern yourself with unless you will have large numbers
(order of 10^6 - perhaps more) of small (16 bytes or smaller) objects
(my opinion - take with grain-o-salt). Even then, I might be too
conservative.

The big reason for using a non-virtual function is if you want to allow
the compiler to inline the function. The compiler will have a very hard
time (possibly impossible) in-lining a the virtual function.

Sep 9 '06 #2
yp*********@ind iatimes.com wrote:
Hello All,

So far I have been reading that in case of a polymorphic class ( having
at least one virtual function in it), the virtual function call get
resolved at run time and during that the vtable pointer is made use
of..

eg.
class one
{
virtual void fun1(){ cout<<"one::fun 1";} //This is a virtual
function.
void fun2(){ cout<<"one ::fun2";}//Not a virtual function.

};

so when the virtual function gets called through the base class poitner
the call actually gets expanded to the code like this
o->vfptr[0]();
Yes, at least for C++ compilers that use vtables to implement virtual
functions. But the general point is that one function call to a virtual
method in the source code can - at runtime - execute any of several
distinct methods (based on the runtime type of the object) each and
every time. So calling a virtual method requires run-time
decision-making which is not needed when calling non-virtual methods or
global functions.
My confusion is how the call to the non virtual function (here fun2
)gets resolved in polymorphic class?
When does the compiler decide to look into the vtable and when not to
look?
The compiler generates "lookup-code" when the method being called has
been declared virtual, otherwise it generates a direct call to the
method as determined by the object's static type.
As in this scenario I strongly feel that, every time the compiler has
to look into the vtable irrespective of the virtuality or non
virtuality of the function.If it finds the function entry in the vtable
then it calls the function from there otherwise if it doesn't find any
entry into the vtable it looks for the non virtual function and then
execute the fuction code?
The program at runtime does not need to determine whether a method is
virtual or not. The compiler has that information at compile time - so
only calls to virtual methods will have the overhead of a virtual
method call.
So in other words whenever your class is polymorphic , we have to deal
with this overhead always whether the class user calls the virtual or
non virtual function...
No, that is not the case at all.

Greg
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]

Sep 9 '06 #3
<yp*********@in diatimes.comsch rieb im Newsbeitrag
news:11******** **************@ i42g2000cwa.goo glegroups.com.. .
Hello All,

So far I have been reading that in case of a polymorphic class ( having
at least one virtual function in it), the virtual function call get
resolved at run time and during that the vtable pointer is made use
of..

eg.
class one
{
virtual void fun1(){ cout<<"one::fun 1";} //This is a virtual
function.
void fun2(){ cout<<"one ::fun2";}//Not a virtual function.

};

int main()
{
one * o = new one;
o->fun1();
o->fun2();
delete o;
o= NULL;
return 0;
}

so when the virtual function gets called through the base class poitner
the call actually gets expanded to the code like this
o->vfptr[0]();
My confusion is how the call to the non virtual function (here fun2
)gets resolved in polymorphic class?
When does the compiler decide to look into the vtable and when not to
look?
As in this scenario I strongly feel that, every time the compiler has
to look into the vtable irrespective of the virtuality or non
virtuality of the function.If it finds the function entry in the vtable
then it calls the function from there otherwise if it doesn't find any
entry into the vtable it looks for the non virtual function and then
execute the fuction code?
There is one error in your Concept of a compiler. Compilers don't call the
functions they compile. They generate code to call them, and this code
depends on, among other things, a functions firtuaity or non- virtually.
When the compiler detects a call to a virtual function, it may indeed emit
some code to fetch the function's address from a "vtable". But if a
non-virtual function should be called, the compiler can insert the address
directly into the code.

Also, the compiler does not use a "vtable" to decide whether a function is
virtual or not. Usually compilers have much more complicated tables, which
also contain a function's name, its return type, number and type of its
parameters, and perhaps many other data. And the compiler has to look-up
each identifier in this table. No matter what that identifier is used for.
Actually, the compiler has to look-up the identifier to determine what the
identifier is used for.
So in other words whenever your class is polymorphic , we have to deal
with this overhead always whether the class user calls the virtual or
non virtual function...
At compile-time, that might be correct but even worse -- even if a class is
not polymorphic, it still takes about the same time to compile a function
call. But there might be a difference at run-time.

HTH
Heinz
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]

Sep 9 '06 #4
{ Quoted sig & clc++m banner removed. -mod }

yp*********@ind iatimes.com wrote:
Hello All,

So far I have been reading that in case of a polymorphic class ( having
at least one virtual function in it), the virtual function call get
resolved at run time and during that the vtable pointer is made use
of..

eg.
class one
{
virtual void fun1(){ cout<<"one::fun 1";} //This is a virtual
function.
void fun2(){ cout<<"one ::fun2";}//Not a virtual function.

};

int main()
{
one * o = new one;
o->fun1();
o->fun2();
delete o;
o= NULL;
return 0;
}

so when the virtual function gets called through the base class poitner
the call actually gets expanded to the code like this
o->vfptr[0]();
My confusion is how the call to the non virtual function (here fun2
)gets resolved in polymorphic class?
When does the compiler decide to look into the vtable and when not to
look?
As in this scenario I strongly feel that, every time the compiler has
to look into the vtable irrespective of the virtuality or non
virtuality of the function.If it finds the function entry in the vtable
then it calls the function from there otherwise if it doesn't find any
entry into the vtable it looks for the non virtual function and then
execute the fuction code?
So in other words whenever your class is polymorphic , we have to deal
with this overhead always whether the class user calls the virtual or
non virtual function...

Can anyone please clarify it..?
My english is bad, by-your-leave.
If you write a class like this:

class One
{
public:
virtual void fun1() { cout<<"one::fun 1"; }
void fun2() { cout<<"one::fun 2"; }
};

And make the call like this:

One *p = new One;
p->fun1();
p->fun2();
delete p;

In fact, for the compiler, it's might looks like this:

p = _new(sizeof(One ));

(*p->vtbl[0])(p);

fun2(p);

if (p != 0)
{
_delete (p);
}

Actually, if a function is non-virtual in a (polymorphic) class,
it will be resolved a static-call at compiler-time.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]

Sep 9 '06 #5
yp*********@ind iatimes.com wrote:
Hello All,

So far I have been reading that in case of a polymorphic class (
having at least one virtual function in it), the virtual function
call get resolved at run time and during that the vtable pointer is
made use of..
Yes.
>
eg.
class one
{
virtual void fun1(){ cout<<"one::fun 1";} //This is a virtual
function.
void fun2(){ cout<<"one ::fun2";}//Not a virtual function.

};

int main()
{
one * o = new one;
o->fun1();
o->fun2();
delete o;
o= NULL;
return 0;
}

so when the virtual function gets called through the base class
poitner the call actually gets expanded to the code like this
o->vfptr[0]();
My confusion is how the call to the non virtual function (here fun2
)gets resolved in polymorphic class?
When does the compiler decide to look into the vtable and when not
to
look?
The compiler knows at compile time which functions are virtual, and
which are not. So it can generate vtable lookups only for those
functions that need it.
As in this scenario I strongly feel that, every time the compiler
has
to look into the vtable irrespective of the virtuality or non
virtuality of the function.If it finds the function entry in the
vtable then it calls the function from there otherwise if it doesn't
find any entry into the vtable it looks for the non virtual function
and then execute the fuction code?
No, the compiler decides which functions to put in the vtable, so it
already knows this at compile time.
So in other words whenever your class is polymorphic , we have to
deal
with this overhead always whether the class user calls the virtual
or
non virtual function...
No, not really.

A smart compiler can optimize you example even more. To be really
polymorphic, there has to be another class present, that inherits from
one and overrides fun1(). As there is not, all calls to fun1() must be
to the function in class one.

So the compiler can skip the vtable altogether, and always call fun1()
directly. That way the overhead will be the same for both functions!
:-)
Bo Persson

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]

Sep 9 '06 #6
Dnia Fri, 08 Sep 2006 19:21:25 -0400, ypjofficial napisa(a):
so when the virtual function gets called through the base class poitner
the call actually gets expanded to the code like this
o->vfptr[0]();
This is right.
My confusion is how the call to the non virtual function (here fun2
)gets resolved in polymorphic class?
When does the compiler decide to look into the vtable and when not to
look?
Compilers use class declaration. When a method is virtual it is clearly
stated in the code of a class or its base classes. (With the 'virtual'
keyword.) When a method is not virtual, the compiler uses method from the
class the pointer has type of. (See example)

Therefore, have no worries, non virtual methods are never called using
VTable. In fact, even virtual methods may not use it (i'm not sure
about wording The Standard puts here, but imho it may not be necessary).

VTable must be used when you call some virtual method using a pointer or a
reference to the class.

struct Base; {
virtual void v_method();
void method();
};
struct Derived : public Base {
virtual void v_method();
void method();
};

Base b;
Derived d;
Base* pb = &d;

b.v_method(); // not here
d.v_method(); // not here
pb->v_method(); // here

pb->method(); // calls Base::method()

That example does something one should not do. It overrides nonvirtual
method, what is not forbidden by the standard, but is a bad practise as it
misleads users of your class.

Regards,
--
Tomek 'QsoRiX' Rydzyski Linux Registered User #178082
http://rtfm.killfile.pl/ http://apcoln.linuxpl.org/

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]

Sep 9 '06 #7
Bob
yp*********@ind iatimes.com wrote:
Hello All,

So far I have been reading that in case of a polymorphic class (
having at least one virtual function in it), the virtual function
call get resolved at run time and during that the vtable pointer is
made use of..

eg.
class one
{
virtual void fun1(){ cout<<"one::fun 1";} //This is a virtual
function.
void fun2(){ cout<<"one ::fun2";}//Not a virtual function.

};

int main()
{
one * o = new one;
o->fun1();
o->fun2();
delete o;
o= NULL;
return 0;
}

so when the virtual function gets called through the base class
poitner the call actually gets expanded to the code like this
o->vfptr[0]();
My confusion is how the call to the non virtual function (here fun2
)gets resolved in polymorphic class?
When does the compiler decide to look into the vtable and when not to
look?
As in this scenario I strongly feel that, every time the compiler has
to look into the vtable irrespective of the virtuality or non
virtuality of the function.If it finds the function entry in the
vtable then it calls the function from there otherwise if it doesn't
find any entry into the vtable it looks for the non virtual function
and then execute the fuction code?
So in other words whenever your class is polymorphic , we have to deal
with this overhead always whether the class user calls the virtual or
non virtual function...

Can anyone please clarify it..?
When the *compiler* is able to determine the exact type of object,
then it is able to call the function statically.

If all it is given is a pointer (or reference) to a polymorphic
base class, then the compiler can make no assumptions about the
exact type of object.

So, for example;
class A
{
public:
virtual void f();
};

class B : public A
{
public:
virtual void f();
};

int main()
{
B b;
b.f(); // calls B::f() statically as b's type is known
A a;
A *pa = &a;
pa->f(); // uses virtual function dispatch and calls A::f()
pa = &b;
pa->f(); // uses virtual function dispatch and calls B::f()
}

Within the body of a constructor, the static type of an object is
the type corresponding to the constructor. So, if A's constructor
calls f(), A::f() will be called statically and, if B's constructor
calls f(), B::f() will be called statically.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]

Sep 9 '06 #8
yp*********@ind iatimes.com schrieb:
Hello All,

[... about vptr lookup ...]

so when the virtual function gets called through the base class poitner
the call actually gets expanded to the code like this
o->vfptr[0]();
You seem to have read the FAQ already, but I'll post it nonetheless for
the sake of reference:

http://www.parashift.com/c++-faq-lit...functions.html
My confusion is how the call to the non virtual function (here fun2
)gets resolved in polymorphic class?
When does the compiler decide to look into the vtable and when not to
look?
At compile-time. The compiler knows what functions are virtual, and
what functions are non-virtual; note that if a specific function is
marked as virtual somewhere in the class hierarchy, then it is
automatically virtual for all classes *deriving* from this class.

"Good coding style(tm)" proposes to use the virtual keyword in any class
for this method, as it shows a conscious decision.

I think, you are worried of this:

// --- in our all known header file
struct I_blub {
virtual void v_method() = 0;
void method() {}; // note: non-virtual
};
// --- in a third party component anywhere, only binary linked.
struct CThirdParty : I_blub {
virtual void v_method() { }
virtual void method() { } // note: *virtual*!
};

This probably won't work as expected. If you now do

CThirdParty obj;
obj.method();

then it is clear, that the CThirdParty::me thod() will be called. But if
you think you can do:

I_blub *my_obj= &obj;
my_obj->method();

you will be surprised. Indeed I_blub::method( ) will be called. This is
becase for I_blub the compiler knows that method() is *non-virtual*, and
will therefore not do a look-up. Never.
As in this scenario I strongly feel that, every time the compiler has
to look into the vtable irrespective of the virtuality or non
virtuality of the function.If it finds the function entry in the vtable
then it calls the function from there otherwise if it doesn't find any
entry into the vtable it looks for the non virtual function and then
execute the fuction code?
Why do you feel so? Every function is known to be virtual or
non-virtual at compile-time, for a specific class. If you derive from a
class, and add some virtual to a known method, you did not change the
base class. If somebody accesses your class via base, the virtual in
your derived class has no effect.
So in other words whenever your class is polymorphic , we have to deal
with this overhead always whether the class user calls the virtual or
non virtual function...

Can anyone please clarify it..?
I hope I could help a bit.

As a final remark I want to add, that with current compiler optimization
there may already be some tricks to decrease the cost of virtual
function calls, I'm thinking of profile guided optimization here. I
don't know exactly what is done there, but I think it has to do with
speculative execution of some virtual function call or so. I hope one
of the other readers may point to some resource.
best regards,
-- Markus
Thanks and Regards,
Yogesh Joshi
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]

Sep 9 '06 #9
yp*********@ind iatimes.com wrote :
My confusion is how the call to the non virtual function (here fun2
)gets resolved in polymorphic class?
o is of type one*.
Therefore o->fun1() calls one::fun1 with o as 'this'.
When does the compiler decide to look into the vtable and when not to
look?
It looks into the vtable when the function is virtual.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]

Sep 9 '06 #10

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

Similar topics

5
4653
by: Praveen Srinivasan | last post by:
Hi all, Are there any important issues that one should be aware of when calling C++ functions from C? In particular, I'm passing a function pointer to a C routine in a library, and in that function I do C++ type stuff, e.g. utilizing operator overloading. Is that reasonable, or are there some pitfalls I need to watch out for? Thanks, Praveen Srinivasan
3
12105
by: Roy Yao | last post by:
Hello, I need to pass a pointer to a callback function to the lower level modules. But the function is thought to be a virtual member one. How can I get the real address of the virtual member function?
3
2523
by: Philippe Guglielmetti | last post by:
Look at these few lines of code: class A { public: virtual void f() { cout << "A";}}; class B : public A{public: static void f() { cout << "B"; }}; class C : public B{public: void f() { cout << "C"; }}; // virtual or not ? that's the question... int main(int, char**) { A* x; A a; B b; C c;
2
1918
by: William Payne | last post by:
Hello, consider these following two classes. A base class, class MDIChildWindow, and a class inherting from that base class, class Document. In the static base member function callback() I obtain a pointer to the child class and call the function on_mdiactivate() using this pointer. For some reason, the program executes MDIChildClass::on_mdiactivate() and not Document::on_mdiactivate(). Why? on_mdiactivate() is a virtual function in...
3
11438
by: scott | last post by:
hi all, hope some one can help me. Ill try and explain what im trying to do as best i can. i have a parent class that has a vertual function, lets call it virtual int A(). That vertual function does somthing that must be done. This meens that when a child class inherits the class and creates its own vertual int A() the parent class must also be called. the prob is i can not use the base class name and then its functino name after it...
6
2247
by: BigMan | last post by:
Is it safe to call nonvirtual member functions from ctors and dtors? What about virtual ones?
1
1560
by: question | last post by:
I want to know incase there is any performance difference or overhead in calling a base class method and a derived class method. Basically I am talking about simple method that is not overridden nor virtual. If I declare a method in the base class say M1() and another in derived class M2(). Then I make a derived class object derived. I then invoke these: derved.M1() derived.M2()
3
1914
by: marcwentink | last post by:
Say I have a class A, and a class B that inherits from A. Now A (and B) has a virtual destructor and a virtual function F(); If I now make these statements A* ptrA = new B; ptrA->F(); delete ptrA then in the statement ptrA->F(), by means of the polymorph behavior,
7
3086
by: eric | last post by:
hello i'm confused by an example in the book "Effective C++ Third Edition" and would be grateful for some help. here's the code: class Person { public: Person(); virtual ~Person(); // see item 7 for why this is virtual ...
0
8801
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
9174
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
9074
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
9015
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...
0
7953
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6634
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
5947
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4464
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...
0
4725
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

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.