CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    Join Date
    Feb 2006
    Posts
    13

    once virtual, always virtual?

    So, I was recently reading mozilla's portability FAQ and item #25 surprised me and I was wondering if anyone could lend some insight to what I have always thought in the past.

    http://www.mozilla.org/hacking/porta..._on_subclasses

    According to them once something is virtual it will always be which means to me it can therefore not be inlined and will always require a vtable. However, I always thought that in the following example the call to b.foo() would be inlined (and maybe even a->foo() on really tricky optimizing compilers though certainly not to be expected in more complex cases).

    Code:
    class A
    {
    public:
        virtual void foo() { cout << "A" << endl; }
    };
    
    class B
    {
    public:
        void foo() { cout << "B" << endl; }
    };
    
    int main()
    {
        B b;
        b.foo();
        A* a = &b;
        a->foo();
        return 0;
    }
    I do believe them that this might not be entirely portable though I'm not too concerned with that as we only need to support a small number of compilers, but I would like to know if there is a reason that my belief that b.foo() would be inlined is wrong and if so why that might be.

    Thanks

  2. #2
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128

    Re: once virtual, always virtual?

    Shouldn't you be inheriting class B from class A?

    Code:
    class A
    {
    public:
        virtual void foo() { cout << "A" << endl; }
    };
    
    class B: public A
    {
    public:
        void foo() { cout << "B" << endl; }
    };
    
    int main()
    {
        B b;
        b.foo();
        A* a = &b;
        a->foo();
        return 0;
    }
    Anyway, the b::foo couldn't be inlined because A::foo is being declared as virtual. As a result, the vtable will be used whenever foo is being invoked.
    quoted from C++ Coding Standards:

    KISS (Keep It Simple Software):
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.

    Avoid magic number:
    Programming isn't magic, so don't incant it.

  3. #3
    Join Date
    Feb 2006
    Posts
    13

    Re: once virtual, always virtual?

    Yeah, sorry, I meant to inherit B from A.

    So I guess the answer is though that things will always be virtual which is kind of disappointing. I always thought taking out the virtual would effectively end the vtable and allow things to be optimized when enought type information was available.

    Thanks for the answer.

  4. #4
    Join Date
    Dec 2004
    Location
    Poland
    Posts
    1,165

    Re: once virtual, always virtual?

    In your example when you are calling b.foo() no virtual mechanism is used, because b is an object, not a reference nor pointer. Type of b is known and there is no need to use vtable, so call could be inlined.

    Regards,
    Hob
    B+!
    'There is no cat' - A. Einstein

    Use &#91;code] [/code] tags!

    Did YOU share your photo with us at CG Members photo gallery ?

  5. #5
    Join Date
    Feb 2005
    Location
    "The Capital"
    Posts
    5,306

    Re: once virtual, always virtual?

    Quote Originally Posted by spitzerg
    So I guess the answer is though that things will always be virtual which is kind of disappointing. I always thought taking out the virtual would effectively end the vtable and allow things to be optimized when enought type information was available.
    Nopes.. the virtual keyword in the over-ride is redundant (but still has the virtual effect as declared in the base class) but it is always better to keep it... to make it informative. Regards.

  6. #6
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: once virtual, always virtual?

    Quote Originally Posted by exterminator
    Nopes.. the virtual keyword in the over-ride is redundant (but still has the virtual effect as declared in the base class) but it is always better to keep it... to make it informative. Regards.
    My preferred style is to only use virtual when the function is first introduced, and to clearly mark out the overrides in derived classes (but without the virtual):
    Code:
    class foo1
    {
    public:
    	virtual int foo1m1(int) = 0;
    	virtual void foo2m2() = 0;
    };
    
    class foo2
    {
    public:
    	virtual int foo2m1() = 0;
    };
    
    class bar : public foo1, public foo2
    {
    public:
    	// bar's own functions
    
    public:
    	//! @name From foo1
    	//@{
    	int foo1m1(int);
    	void foo1m2();
    	//@}
    
    public:
    	//! @name From foo2
    	//@{
    	int foo2m1();
    	//@}
    };
    Note the redundant use of the access specifier - I use it to clearly mark different conceptual sections of the class interface (I'll also use separate privates for private functions and private data). The doxygen comment style also helps to keep related functions together in the generated documentation.

    Just my style - I'm not suggesting that it's better than anyone else's.
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  7. #7
    Join Date
    Jun 2002
    Posts
    1,417

    Re: once virtual, always virtual?

    My compiler (VC++ 6.0) always gives me errors if I don't use virtual keyword in derived class -- so I just copy-paste from base class where pure virtual function is declared into implementation derived class then remove "= 0" part. I know that compiler is old and not very well compliant.

  8. #8
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: once virtual, always virtual?

    Quote Originally Posted by stober
    My compiler (VC++ 6.0) always gives me errors if I don't use virtual keyword in derived class -- so I just copy-paste from base class where pure virtual function is declared into implementation derived class then remove "= 0" part. I know that compiler is old and not very well compliant.
    I use VC6 and don't have that problem...
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  9. #9
    Join Date
    Dec 2005
    Posts
    642

    Re: once virtual, always virtual?

    Quote Originally Posted by spitzerg
    According to them once something is virtual it will always be which means to me it can therefore not be inlined and will always require a vtable.
    The compiler is allowed (but not required) to bind calls to virtual functions at compile time (i.e. call them non-virtually) if it can determine the exact type of the object on which the function is being called at compile time. In your example it can. In constructors it also can (since in constructors, this is always assumed to point to an object whose exact type is the one being constructed. similary for destructors.)

    I think that's what you meant by inlining (calling non-virtually.) However inlining has a different meaning. If the compiler can bind the virtual call at compile-time and if the body of the target function is available for inlining, it's allowed (although again, not required) to inline the called function into the calling function. In your example B::foo is available, so it may get inlined into the body of main.

    Whenever you want to know what your compiler is doing with your code, it's best to generate an assembly language listing, or disassemble the object file and see for yourself what kind of code was generated.

  10. #10
    Join Date
    Jun 2002
    Location
    Moscow, Russia.
    Posts
    2,176

    Re: once virtual, always virtual?

    Quote Originally Posted by spitzerg
    According to them once something is virtual it will always be which means to me it can therefore not be inlined and will always require a vtable. However, I always thought that in the following example the call to b.foo() would be inlined.
    So your confusion has nothing to do with mozilla FAQ... C++ standard doesn't define implementation of code (generated by compilers), it only define behaviour. So when something may be optimized, it can be optimized. Compiler may even estimate that in most cases object has certain type and inline anyway, adding befor it single check for other cases.
    "Programs must be written for people to read, and only incidentally for machines to execute."

  11. #11
    Join Date
    Aug 2005
    Location
    San Diego, CA
    Posts
    1,054

    Re: once virtual, always virtual?

    I understand why someone would have their own personal style with comments. But if you develop code that other people might someday maintain, PLEASE put the virtual key word in derived classes. Why would one think that less information would be clearer? Many professionals end up having to maintain some amount of code that someone else wrote. Complex inheritance hierachies can be terribly difficult to maintain. If the function is virtual, mark it virtual so that I don't have to go up 4 levels in base classes to figure out if something is virtual.

    The only reason I could think to not use virtual is if there is a structural reason for doing so. If a class was designed so that it could exist by itself or inherit from something, I could understand not using virtual in the derived class declarations. Most of the time if I am implementing a base class with a derived class, I am going to always use that class as a derived class anyway; so what good does it do me to purposely omit the virtual keyword from the derived class function declarations? Seriously, if someone could please explain the benefit of omitting the keyword, I'd appreciate it. Maybe there is something I can learn about C++ from this thread.

    Quote Originally Posted by Graham
    My preferred style is to only use virtual when the function is first introduced, and to clearly mark out the overrides in derived classes (but without the virtual):
    Code:
    class foo1
    {
    public:
    	virtual int foo1m1(int) = 0;
    	virtual void foo2m2() = 0;
    };
    
    class foo2
    {
    public:
    	virtual int foo2m1() = 0;
    };
    
    class bar : public foo1, public foo2
    {
    public:
    	// bar's own functions
    
    public:
    	//! @name From foo1
    	//@{
    	int foo1m1(int);
    	void foo1m2();
    	//@}
    
    public:
    	//! @name From foo2
    	//@{
    	int foo2m1();
    	//@}
    };
    Note the redundant use of the access specifier - I use it to clearly mark different conceptual sections of the class interface (I'll also use separate privates for private functions and private data). The doxygen comment style also helps to keep related functions together in the generated documentation.

    Just my style - I'm not suggesting that it's better than anyone else's.

  12. #12
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: once virtual, always virtual?

    Please note the last sentence of my post.

    I might also point out that that particular style is part of the Symbian coding guidelines...
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  13. #13
    Join Date
    Aug 2005
    Location
    San Diego, CA
    Posts
    1,054

    Re: once virtual, always virtual?

    I understand that it is preference. I'm just curious as to *why* it is a preference and why it would be part of a coding standard. I've worked in a lot of large organizations where people code like this and it seems harder to understand the code. You end up having to chase the first declaration of a function up the inheritance ladder until you find the first declaration in order to verify that a particular function is virtual. I wasn't trying to insult your preference; I'm trying to understand the reasoning of this preference. So again; if anyone has any ideas on that, I'd appreciate it. Sometimes we just follow guidelines without knowing why. In this case, I don't like the guideline, personally, but if there is a good reason to use it I'd like to know what it is.

    Best Regards,

    Shawn

  14. #14
    Join Date
    Jun 2002
    Location
    Moscow, Russia.
    Posts
    2,176

    Re: once virtual, always virtual?

    Actually with modern IDEs who's going to look in 4 files to determine if something's virtual function? It's all visualized in place already...
    But I see no reason for ommiting virtual keyword either. Inheritance is breaking of encapsulation already, so it's better to emphasize on where it intervenes.
    Last edited by RoboTact; February 27th, 2006 at 07:01 PM.
    "Programs must be written for people to read, and only incidentally for machines to execute."

  15. #15
    Join Date
    Feb 2005
    Location
    "The Capital"
    Posts
    5,306

    Re: once virtual, always virtual?

    Quote Originally Posted by kempofighter
    I understand that it is preference. I'm just curious as to *why* it is a preference and why it would be part of a coding standard. I've worked in a lot of large organizations where people code like this and it seems harder to understand the code. You end up having to chase the first declaration of a function up the inheritance ladder until you find the first declaration in order to verify that a particular function is virtual. I wasn't trying to insult your preference; I'm trying to understand the reasoning of this preference. So again; if anyone has any ideas on that, I'd appreciate it. Sometimes we just follow guidelines without knowing why. In this case, I don't like the guideline, personally, but if there is a good reason to use it I'd like to know what it is.
    Quote Originally Posted by RoboTact
    Actually with modern IDEs who's going to look in 4 files to determine if something's virtual function? It's all visualized in place already...
    But I see no reason for ommiting virtual keyword either. Inheritance is breaking of encapsulation already, so it's better to emphasize on where it intervenes.
    There could be cases when you omit the keyword .. just to differentiate a virtual function from the most-derived class and a virtual function introduced in the middle of the hierarchy. I know, you may say that the classes deriving from that intermediate one doesnot need to know where the roots of that virtual are but still it does make sense to me.

    Guidelines are just guidelines - they are not standards. Graham said it was a coding guideline and not a coding standard. There is difference between the two. With a guideline - if you feel you want to over-ride it for the better sense.. do it. I don't think there is a problem but you got to mention it somewhere. Regards.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured