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

Discussion in 'C++' started by ypjofficial@indiatimes.com, Sep 9, 2006.

  1. Guest

    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::fun1";} //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++.moderated. First time posters: Do this! ]
    , Sep 9, 2006
    #1
    1. Advertising

  2. 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.
    Gianni Mariani, Sep 9, 2006
    #2
    1. Advertising

  3. Greg Herlihy Guest

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

    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::fun1";} //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++.moderated. First time posters: Do this! ]
    Greg Herlihy, Sep 9, 2006
    #3
  4. Aman JIANG Guest

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

    { Quoted sig & clc++m banner removed. -mod }

    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::fun1";} //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::fun1"; }
    void fun2() { cout<<"one::fun2"; }
    };

    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++.moderated. First time posters: Do this! ]
    Aman JIANG, Sep 9, 2006
    #4
  5. Heinz Ozwirk Guest

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

    <> schrieb im Newsbeitrag
    news:...
    > 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::fun1";} //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++.moderated. First time posters: Do this! ]
    Heinz Ozwirk, Sep 9, 2006
    #5
  6. Bo Persson Guest

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

    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::fun1";} //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++.moderated. First time posters: Do this! ]
    Bo Persson, Sep 9, 2006
    #6
  7. Re: same overhead in calling virtual and non virtual member function...?

    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-lite/virtual-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::method() 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++.moderated. First time posters: Do this! ]
    Markus Grueneis, Sep 9, 2006
    #7
  8. Re: same overhead in calling virtual and non virtual member function...?

    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++.moderated. First time posters: Do this! ]
    Tomek RydzyÅski, Sep 9, 2006
    #8
  9. loufoque Guest

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

    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++.moderated. First time posters: Do this! ]
    loufoque, Sep 9, 2006
    #9
  10. Bob Guest

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

    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::fun1";} //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++.moderated. First time posters: Do this! ]
    Bob, Sep 9, 2006
    #10
  11. * :
    > 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.

    First off, the language does not require a vtable, although in practice
    all implementations you're likely to encounter are vtable-based.

    If a function is non-virtual the function address (where its code
    resides in memory) is known at compile time, at least symbolically.
    That's all you need to issue a call to the function. When a function is
    virtual and is called virtually in the source code, the function address
    is not necessarily known at compile time, because it then depends on the
    object the function is called on, so in that case the compiler may have
    to insert code that looks up the function address in the vtable
    specified by the object.

    <netiquette>
    By the way, please don't cross-post to clc++ and clc++m.

    Generally you get answers faster in clc++, but when you're crossposting
    to a moderated group every article is held up in all groups until it's
    accepted (or rejected), so you don't get faster answers: at best you
    gain a somewhat broader audience, but some answers you'd otherwise have
    had may not be posted (because some posters don't care to wait for the
    turnaround of a moderated group), some answers you'd otherwise have had
    may be rejected, you run a much higher chance of thread drift, and
    you're annoying and worse those who unwittingly reply to your clc++
    article expecting their response to show up more or less immediately.

    Multiposting -- posting separately -- is an even worse idea, because
    the poster then Really Annoys those who reply in one group only to find
    the same article posted separately in another group.

    A month or two ago there was a surge of multiposting in clc++m. I
    generally think of those who multi-post without reason as being either
    idiots or non-caring egoists or both (unless they are clearly
    first-timers on the net), and I would not be surprised if that's how
    most others also view them. Happily multi-posting is not what you did
    here, but don't do it. ;-)
    </netiquette>

    --
    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?

    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
    Alf P. Steinbach, Sep 10, 2006
    #11
  12. James Kanze Guest

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

    Greg Herlihy wrote:
    > wrote:


    > > 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
    > > eg.
    > > of..


    > > class one
    > > {
    > > virtual void fun1(){ cout<<"one::fun1";} //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.


    More strictly speaking: if the compiler doesn't know at compile
    time which function to call, it must generate code to determine
    this at run-time. By definition, if the function isn't virtual,
    the compiler does know this at run time. If the function is
    virtual, it may or may not know it, depending on how good it is.
    Almost all compilers will know it if the call is through an
    actual object; if the call is through a reference or a pointer,
    it depends on the quality of the optimizer.

    --
    James Kanze (Gabi Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
    James Kanze, Sep 10, 2006
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. slide_o_mix
    Replies:
    0
    Views:
    401
    slide_o_mix
    Oct 15, 2003
  2. Alex
    Replies:
    0
    Views:
    373
  3. Replies:
    5
    Views:
    572
  4. archimed7592
    Replies:
    4
    Views:
    726
    =?UTF-8?B?UGF3ZcWC?=
    May 30, 2007
  5. ittium
    Replies:
    5
    Views:
    425
    88888 Dihedral
    Jan 12, 2012
Loading...

Share This Page