CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 3 123 LastLast
Results 1 to 15 of 45
  1. #1
    George2 is offline Elite Member Power Poster
    Join Date
    Oct 2002
    Posts
    4,468

    Compiler Warning C4373 about virtual methods

    Hello everyone,


    The following code will result in C4373 warning message. In MSDN,

    http://msdn2.microsoft.com/en-us/library/bb384874.aspx

    I do not quite understand the following statement,

    1. What means "bind"? Putting function pointer into the vtable of the related class?

    2. const is ignored in derived class?

    --------------------
    This means the compiler must bind a function reference to the method in either the base or derived class.

    Versions of the compiler prior to Visual C++ 2008 bind the function to the method in the base class, then issue a warning message. Subsequent versions of the compiler ignore the const or volatile qualifier, bind the function to the method in the derived class, then issue warning C4373. This latter behavior complies with the C++ standard.
    --------------------

    Code:
    class Base {
    public:
    	virtual int goo (const int input) {return 200;}
    };
    
    class Derived : public Base {
    public:
    		virtual int goo (int input) {return 200;} // change const property of input parameter
    };
    
    int main()
    {
    	Derived d;
    	const int a = 1000;
    	d.goo (a); // pass const to non-const
    
    	return 0;
    }
    Compile warning message,

    1>d:\visual studio 2008\projects\test_overriding1\test_overriding1\main.cpp(8) : warning C4373: 'Derived::goo': virtual function overrides 'Base::goo', previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers
    1> d:\visual studio 2008\projects\test_overriding1\test_overriding1\main.cpp(3) : see declaration of 'Base::goo'


    regards,
    George

  2. #2
    Join Date
    Oct 2006
    Location
    Singapore
    Posts
    346

    Re: Compiler Warning C4373 about virtual methods

    Hey George,

    1. Yes, in this context, "binding to a class" means associating the vTable pointer to the corresponding function in that class.
    2. Are you asking if the constness of a is lost in Derived::goo()? Yes, that is correct. However, since you are passing a by value (you can't pass a by non-const reference), whatever changes you make to the parameter inside the function will not affect a. Incidentally, MinGW 3.7 does not give any warning and successfully binds the function to the derived class method. Wonder why Microsoft took so long to realise this?
    Believe in your Dreams, Work for what you Believe in.
    My thoughts? Angelo's Stuff
    Some fun things I've done: RayWatch, QuickFeed, ACSVParser

    @ngelo

  3. #3
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Compiler Warning C4373 about virtual methods

    On a related note, I just encountered the old "class has virtual functions but non-virtual destructor" warning.

    I know I've encountered and dealt with this before, but the details are slipping my mind at the moment.

    The base class is pure-virtual, existing only so that I can use common accessor functions on several derived classes. No destructors are explicitly defined for any of them; they contain only POD and some STL containers (which have their own destructors), so I assumed the default destructor would be good enough.

    What do I need to do to make the warning go away? (Besides just disabling it, of course.)

  4. #4
    Join Date
    Oct 2006
    Location
    Singapore
    Posts
    346

    Re: Compiler Warning C4373 about virtual methods

    Hey Lindley,
    Could you post some working code illustrating the problem?
    Believe in your Dreams, Work for what you Believe in.
    My thoughts? Angelo's Stuff
    Some fun things I've done: RayWatch, QuickFeed, ACSVParser

    @ngelo

  5. #5
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Compiler Warning C4373 about virtual methods

    Not easily. However, I can post simplified class declarations. Since this isn't exactly an obscure error, that should be enough to tell me what I'm doing wrong. Google turned up a number of hits on the message, but none of the explanations were completely clear.

    Code:
    class GraphPart
    {
    public:
        virtual void setField(std::string fieldname, std::string value)=0;
        virtual bool cmpField(std::string fieldname, std::string value) const=0;
        virtual const char* getField(std::string fieldname) const=0;
    };
    
    class GraphNode: public GraphPart
    {
    public:
        // data is a mix of non-pointer primitives and STL containers, nothing else
    
        void setField(std::string fieldname, std::string value);
        bool cmpField(std::string fieldname, std::string value) const;
        const char* getField(std::string fieldname) const;
    };
    
    class GraphEdge: public GraphPart
    {
    public:
        // data is non-pointer primitives
    
        void setField(std::string fieldname, std::string value);
        bool cmpField(std::string fieldname, std::string value) const;
        const char* getField(std::string fieldname) const;
    };
    Before anyone mentions it, the reasoning for not using const string references in the parameters is so that const char*-type strings, including literals, may be passed.

  6. #6
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Compiler Warning C4373 about virtual methods

    Before anyone mentions it, the reasoning for not using const string references in the parameters is so that const char*-type strings, including literals, may be passed.
    Eh, but temporaries and literals can be bound to const references.

    EDIT:
    The warning is just that you should declare the base class destructor virtual so as to avoid undefined behaviour if an object of a derived class is deleted through a pointer to the base class.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  7. #7
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Compiler Warning C4373 about virtual methods

    I had previously tried that (the const reference thing), and got errors. Just did again and it worked. Oh well, I must have screwed something up last time.

    Likewise, when I tried adding a pure virtual destructor to the base class I got undefined symbol messages....turns out that even pure virtual classes need actual destructor definitions (!?) in order to compile, even when they're virtual.

  8. #8
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Compiler Warning C4373 about virtual methods

    Likewise, when I tried adding a pure virtual destructor to the base class I got undefined symbol messages....turns out that even pure virtual classes need actual destructor definitions (!?) in order to compile, even when they're virtual.
    Yes, that is true. It sounds like you just ran into a stroke of bad luck or something, heheh.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  9. #9
    Join Date
    Oct 2006
    Location
    Singapore
    Posts
    346

    Re: Compiler Warning C4373 about virtual methods

    Quote Originally Posted by Lindley
    On a related note, I just encountered the old "class has virtual functions but non-virtual destructor" warning.

    I know I've encountered and dealt with this before, but the details are slipping my mind at the moment.

    The base class is pure-virtual, existing only so that I can use common accessor functions on several derived classes. No destructors are explicitly defined for any of them; they contain only POD and some STL containers (which have their own destructors), so I assumed the default destructor would be good enough.

    What do I need to do to make the warning go away? (Besides just disabling it, of course.)
    I know that you need to make the destructor in the base class virtual. Unfortunately, I am not able to reproduce this warning with my VS 2005 compiler. What compiler are you using Lindley?

    Likewise, when I tried adding a pure virtual destructor to the base class I got undefined symbol messages....turns out that even pure virtual classes need actual destructor definitions (!?) in order to compile, even when they're virtual.
    Section 12.4 in the standard:
    A destructor can be declared virtual (10.3) or pure virtual (10.4); if any objects of that class or any derived class are created in the program, the destructor shall be defined.
    Believe in your Dreams, Work for what you Believe in.
    My thoughts? Angelo's Stuff
    Some fun things I've done: RayWatch, QuickFeed, ACSVParser

    @ngelo

  10. #10
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Compiler Warning C4373 about virtual methods

    Quote Originally Posted by angelorohit
    I know that you need to make the destructor in the base class virtual. Unfortunately, I am not able to reproduce this warning with my VS 2005 compiler. What compiler are you using Lindley?
    Neither am I, even on -W4, and that was part of the problem. This came off a list of warnings generated on Linux by g++ on my code that was sent to me. I write all my code to be cross-platform.

    Section 12.4 in the standard:
    A destructor can be declared virtual (10.3) or pure virtual (10.4); if any objects of that class or any derived class are created in the program, the destructor shall be defined.
    If I'm reading that right----mentally substituting "must" for "shall" at the end there----that seems arbitrary, but at least it's something to work from.

  11. #11
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: Compiler Warning C4373 about virtual methods

    1) EVERY class must have a destructor implementation. It can be the "generated" destructor, or an explicitly written destructor. This may be optimized out of existance, but must initialy exist.

    2) When you declare any method (including the destructor) it prevents the creation of a default implementation

    3) The destructor of a base class (even if it has no members) MUST be virtual in order to funcion properly, if any of the derived classes have any data members. Since this can NOT be detected by the compiler by looking at only the base class, it generates a warning:

    Consider:
    Code:
    class Base
    {
        ~Base();  // NOT virtual...
    }
    
    class Derived
    {
        private SomeThing s;
    }
    
    
    B *test = new Derived();
    delete test;
    There is no way for the delete to invoke the (automatic) destricutor of class Derived (a virtual destructor on Base is required). Therefore D::s will never be properly destructed.

    Clear?

    }
    Last edited by TheCPUWizard; February 25th, 2008 at 12:50 PM.
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  12. #12
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Compiler Warning C4373 about virtual methods

    Makes sense. The confusion was mainly on why a pure virtual base class would need a destructor definition, as opposed to merely a declaration that it was virtual.

  13. #13
    George2 is offline Elite Member Power Poster
    Join Date
    Oct 2002
    Posts
    4,468

    Re: Compiler Warning C4373 about virtual methods

    Hi Lindley,


    I have tried to compile your code in Visual Studio 2008, no compile warning/errors.

    Do you have any comments?

    Why your code have something to do with my original question?

    Quote Originally Posted by Lindley
    Not easily. However, I can post simplified class declarations. Since this isn't exactly an obscure error, that should be enough to tell me what I'm doing wrong. Google turned up a number of hits on the message, but none of the explanations were completely clear.

    Code:
    class GraphPart
    {
    public:
        virtual void setField(std::string fieldname, std::string value)=0;
        virtual bool cmpField(std::string fieldname, std::string value) const=0;
        virtual const char* getField(std::string fieldname) const=0;
    };
    
    class GraphNode: public GraphPart
    {
    public:
        // data is a mix of non-pointer primitives and STL containers, nothing else
    
        void setField(std::string fieldname, std::string value);
        bool cmpField(std::string fieldname, std::string value) const;
        const char* getField(std::string fieldname) const;
    };
    
    class GraphEdge: public GraphPart
    {
    public:
        // data is non-pointer primitives
    
        void setField(std::string fieldname, std::string value);
        bool cmpField(std::string fieldname, std::string value) const;
        const char* getField(std::string fieldname) const;
    };
    Before anyone mentions it, the reasoning for not using const string references in the parameters is so that const char*-type strings, including literals, may be passed.

    regards,
    George

  14. #14
    George2 is offline Elite Member Power Poster
    Join Date
    Oct 2002
    Posts
    4,468

    Re: Compiler Warning C4373 about virtual methods

    Hi angelorohit,


    I am confused what do you mean "(you can't pass a by non-const reference)".

    I have shown you the code below, we can pass non-const reference to method goo. Any comments?

    Code:
    class Base {
    public:
    	virtual int goo (const int input) {return 200;}
    };
    
    class Derived : public Base {
    public:
    		virtual int goo (int input) {return 200;} // change const property of input parameter
    };
    
    int main()
    {
    	Derived d;
    	int a = 100;
    	int& ri = a;
    	d.goo (ri); // pass const to non-const
    
    	return 0;
    }
    Quote Originally Posted by angelorohit
    Hey George,

    1. Yes, in this context, "binding to a class" means associating the vTable pointer to the corresponding function in that class.
    2. Are you asking if the constness of a is lost in Derived::goo()? Yes, that is correct. However, since you are passing a by value (you can't pass a by non-const reference), whatever changes you make to the parameter inside the function will not affect a. Incidentally, MinGW 3.7 does not give any warning and successfully binds the function to the derived class method. Wonder why Microsoft took so long to realise this?

    regards,
    George

  15. #15
    George2 is offline Elite Member Power Poster
    Join Date
    Oct 2002
    Posts
    4,468

    Re: Compiler Warning C4373 about virtual methods

    Thanks Lindley,


    What does your term "common accessor functions" mean? I searched for wikipedia and Google, can not find the definition. :-)

    Quote Originally Posted by Lindley
    On a related note, I just encountered the old "class has virtual functions but non-virtual destructor" warning.

    I know I've encountered and dealt with this before, but the details are slipping my mind at the moment.

    The base class is pure-virtual, existing only so that I can use common accessor functions on several derived classes. No destructors are explicitly defined for any of them; they contain only POD and some STL containers (which have their own destructors), so I assumed the default destructor would be good enough.

    What do I need to do to make the warning go away? (Besides just disabling it, of course.)

    regards,
    George

Page 1 of 3 123 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