Compiler Warning C4373 about virtual methods

This is a discussion on Compiler Warning C4373 about virtual methods within the C++ Programming forums, part of the General Programming Boards category; 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 ...

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    1,579

    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\ma in.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\ma in.cpp(3) : see declaration of 'Base::goo'


    regards,
    George

  2. #2
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    In the Derived class, the int parameter to goo() is missing the const keyword.
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  3. #3
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,467
    There are now two functions; one taking a const int argument and another a int argument. You are basically rendering the virtual keyword useless.

    When deriving from a base class and wanting to implement a virtual function, you must declare the function exactly as it was declared in the base class. i.e. the function headers must match. The only exception is when the base class function returns a reference to a some object base class. In that case you are allowed to return a reference to a derived object of that class.

    This process entails only the redefinition of a function. By changing the argument type you in fact creating a new function. The compiler is warning that might not be what you intended.
    Last edited by Mario F.; 02-25-2008 at 06:55 AM.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,670
    >> This latter behavior complies with the C++ standard.
    Correct. It's just a warning for people who upgrade their compiler and may get different results with the same code.

    gg

  5. #5
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,670
    Well, I take that back - it's not about getting different results. It's a new warning that MS added - but for some reason they decided to let you know that the previous version "did the right thing" as well.

    Here's a sample I just tried on VC 6.0 and 2005:
    Code:
    #include <iostream>
    using namespace std;
    
    class Base 
    {
    public:
        virtual void goo (const int input) 
            {cout << "Base(" << input << ")" << endl;}
    };
    
    class Derived : public Base 
    {
    public:
            virtual void goo (int input) 
                {cout << "Derived(" << input << ")" << endl;}
    };
    
    int main()
    {
        const int ci = 1;
        int i = 2;
    
        Derived d;
        d.goo(ci);
        d.goo(i);
    
        Base *b = &d;
        b->goo(ci);
        b->goo(i);
    
        return 0;
    }
    Both versions returned:
    Code:
    Derived(1)
    Derived(2)
    Base(1)
    Base(2)
    gg

  6. #6
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Hi Mario,


    Could you let me know if we change the const property of overridden method, which expected effect of virtual function or other aspects of expected effect is broken please?

    From MSDN, seems all virtual function related expected results are maintained.

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

    Quote Originally Posted by Mario F. View Post
    There are now two functions; one taking a const int argument and another a int argument. You are basically rendering the virtual keyword useless.

    When deriving from a base class and wanting to implement a virtual function, you must declare the function exactly as it was declared in the base class. i.e. the function headers must match. The only exception is when the base class function returns a reference to a some object base class. In that case you are allowed to return a reference to a derived object of that class.

    This process entails only the redefinition of a function. By changing the argument type you in fact creating a new function. The compiler is warning that might not be what you intended.

    Hi Codeplug,

    For your code below, the ouput in Visual Studio 2008 is,

    Derived(1)
    Derived(2)
    Derived(1)
    Derived(2)

    Quote Originally Posted by Codeplug View Post
    Well, I take that back - it's not about getting different results. It's a new warning that MS added - but for some reason they decided to let you know that the previous version "did the right thing" as well.

    Here's a sample I just tried on VC 6.0 and 2005:
    Code:
    #include <iostream>
    using namespace std;
    
    class Base 
    {
    public:
        virtual void goo (const int input) 
            {cout << "Base(" << input << ")" << endl;}
    };
    
    class Derived : public Base 
    {
    public:
            virtual void goo (int input) 
                {cout << "Derived(" << input << ")" << endl;}
    };
    
    int main()
    {
        const int ci = 1;
        int i = 2;
    
        Derived d;
        d.goo(ci);
        d.goo(i);
    
        Base *b = &d;
        b->goo(ci);
        b->goo(i);
    
        return 0;
    }
    Both versions returned:
    Code:
    Derived(1)
    Derived(2)
    Base(1)
    Base(2)
    gg

    regards,
    George

  7. #7
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,614
    It seems the warning makes sense now. The previous versions did the right thing, but 2008 fixes your little mistake for you.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,467
    Hmm... does it? I sure hope it doesn't.

    Am I reading the standard wrong? I'd expect dynamic binding to not happen when I add the const qualifier to one of the arguments of a virtual function in the derived class.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Overriding is determined by equivalent parameter lists according to the overloading rules. 13.1/3 says that top-level cv qualifiers on parameter types do not make for distinct parameter lists. foo(int) and foo(const int) are the same function.

    Thus, the function Derived::foo(const int) overrides Base::foo(int). In MSVC++ versions prior to .Net 2008, the compiler was non-compliant and had the functions be distinct. In 2008, they fixed this bug and made one function override the other. Then they added to the warning so that people who relied on the old behaviour know that they must fix their programs.

    The solution to the whole problem is of course to stop random experiments with adding const qualifiers in random places where they don't have an effect anyway.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,670
    Nice. Well then - I take back my take-back

    Put too much faith in 2005....

    gg

  11. #11
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Great, CornedBee!


    But I do not quite understand what your below solution means. Any pseudo code please?

    Quote Originally Posted by CornedBee View Post
    The solution to the whole problem is of course to stop random experiments with adding const qualifiers in random places where they don't have an effect anyway.

    regards,
    George

  12. #12
    CSharpener vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,484
    It is not a solution - It is an advice.
    Stop writing random code to see what you get.

    Learn the proper syntax for what you need - and write the correct code instead.
    The first 90% of a project takes 90% of the time,
    the last 10% takes the other 90% of the time.

  13. #13
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks vart, random code means the code which I think and create from my mind and does not follow the best practices?


    Quote Originally Posted by vart View Post
    It is not a solution - It is an advice.
    Stop writing random code to see what you get.

    Learn the proper syntax for what you need - and write the correct code instead.

    regards,
    George

  14. #14
    CSharpener vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,484
    yes. The programmer when writing code whats to achieve some goal

    Code:
    char* strcpy(char* dst, const char* src);
    When I put const here I know, that I want to notify the caller, that src string will not be modified inside my function

    When I just start adding additional const without knowing what is the affect - I call it random code

    Code:
    char* const strcpy(char* const dst, const char* const src);
    That is what you are do, so it seems. You are putting different parts of the code here and there, just to see if it will compile, without reading previously, what it will do, and without setting some goal, except to get some strage compiler warning...
    The first 90% of a project takes 90% of the time,
    the last 10% takes the other 90% of the time.

  15. #15
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Why are you trying to change the interface in the first place?
    It's bad practice and confuses people when they expect the parameter to be const, but then in the derived class it's not const...

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  2. Possible circular definition with singleton objects
    By techrolla in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2004, 09:46 AM
  3. gcc problem
    By bjdea1 in forum Linux Programming
    Replies: 13
    Last Post: 04-29-2002, 06:51 PM
  4. C++ XML Class
    By edwardtisdale in forum C++ Programming
    Replies: 0
    Last Post: 12-10-2001, 10:14 PM
  5. Exporting Object Hierarchies from a DLL
    By andy668 in forum C++ Programming
    Replies: 0
    Last Post: 10-20-2001, 01:26 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21