gcc Woverloaded-virtual warnings
Asked Answered
F

3

26

The following C++ code i think is correct, but produce some warnings when compiled with "-Woverloaded-virtual", is the warning bogus or there is a real problem with this code?

If that is a bogus warning what can i do to avoid it, define all the exception virtual variants in derived get rids of the warning but maybe is a better solution

G++ command:

   g++ -c -Woverloaded-virtual test.cpp 
test.cpp:22:18: warning: ‘virtual void intermediate::exception(const char*)’ was hidden [-Woverloaded-virtual]
test.cpp:32:18: warning:   by ‘virtual void derived::exception()’ [-Woverloaded-virtual]

C++ code

using namespace std;

class base
{
public:

    virtual void exception() = 0;
    virtual void exception(const char*) = 0;
};

class intermediate : public base
{
public:

    virtual void exception()
    {
    cerr << "unknown exception" << endl;
    }

    virtual void exception(const char* msg)
    {
    cerr << "exception: " << msg << endl;
    }
};

class derived : public intermediate
{
public:

    virtual void exception() 
    { 
        intermediate::exception("derived:unknown exception");
    }
};
Frisky answered 3/4, 2012 at 14:32 Comment(0)
T
31

The warning means that:
When you are not using dynamic dispatch then your derived class object can only call,

 void exception()     

and it will hide all same named methods of the Base class intermediate.

In order that your derived class object can call all the same named methods in base class intermediate, You need to add the following line to your derived class.

 using intermediate::exception;

Ofcourse, You are in best position to decide if this is a problem or not.

Toadstool answered 3/4, 2012 at 14:36 Comment(3)
How do we suppress this warning if it is intentional?Limpid
I’m not sure, but I would guess void exception(const char* msg) = delete; would work. EDIT: Nope, deleting an overload like that is an error. But I would be surprised if this was ever actually intentional, in well-designed code; you should be able to treat an instance of a derived class like an instance of the base class.Frijol
As pointed out by the other answer, you can redefine it private just fine.Frijol
N
19

The warning is due to the fact that you cannot call derived::exception(const char*) on an object of type derived (or through a pointer to derived), even though the parent class defines it and it is virtual (so you would expect it to be available in derived). To remove the warning, you need to expose that member function in derived:

class derived : public intermediate 
{ 
public: 
  virtual void exception(const char* msg) {intermediate::exception(msg);}
  virtual void exception()  
  {  
    intermediate::exception("derived:unknown exception"); 
  } 
}; 

Or if you do not want to expose it to others, declare it as private with no defintion.

class derived : public intermediate 
{ 
public: 
  virtual void exception()  
  {  
    intermediate::exception("derived:unknown exception"); 
  } 
private:
  void exception(const char* tmp);
}; 

UPDATE: After double-checking (and as pointed out by Als) the using directive, you could do this too:

class derived : public intermediate 
{ 
public: 
  using intermediate::exception; // imports both declarations from intermediate
  virtual void exception() // will not clash with the imported declaration of the
                           // same signature, but properly overriders the parent
                           // class's defition
  {  
    intermediate::exception("derived:unknown exception"); 
  } 
}; 
Nollie answered 3/4, 2012 at 14:39 Comment(3)
To expose the Base class function in derived class all the OP needs to do is add using intermediate::exception;.Toadstool
Actually, no :) I thought of writing using in my original post, but decided against it (for the same reason that I wrote after your first comment, which I have since deleted -- because I thought it would clash). After your comment (and writing mine by instinct) I double-checked to make sure. After finding you were correct, I updated my answer, afer which I have noticed your second comment with the link. Of course you will have to take my ford for it... But I'll update again, so nobody has hard feelings :)Nollie
Anyway, your alternative is great for poor old C++03 coders.Sal
L
0

Please redefine the function:

virtual void exception(const char* msg); in class "derived".

Now your code will compile without any warnings.

Lys answered 25/4, 2013 at 5:53 Comment(3)
It will compile without warnings, but now you’ve created ODR problems if somebody tries to call that. These will probably manifest as linker errors, which are generally harder to read and understand than compiler warnings or compiler errors.Frijol
@DanielH: what does ODR stand for?Gile
It's the one-definition rule, but I don't know what I was thinking when I made the comment because I don't see an ODR violation.Frijol

© 2022 - 2024 — McMap. All rights reserved.