Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7956 Discussions

False positive: warning #1125: function ${A} is hidden by function ${B}

olzhas_r_
New Contributor I
1,237 Views
struct A {
 private:
  virtual void foo() {}  // Side-info: template-method pattern in the real code.
};

struct B : public A {
 private:
  void foo(int) {}
};

The warning is stating that A::foo is hidden by B::foo.

A::foo() is private and cannot be called from B, anyway.

The warning does not happen if A::foo is not virtual.

The compiler version is icpc (ICC) 17.0.1 20161005.

0 Kudos
3 Replies
Judith_W_Intel
Employee
1,237 Views

First, this is not a warning that is enabled by default - You must have
enabled this remark by specifying an additional flag
(like - Woverloaded-virtual or -Wremark, correct?

Secondly, all other compilers that I've tried (GNU and clang) issue a similar diagnostic
on your code, i.e.:

sptel15-670> icpc -c -Woverloaded-virtual bug.cpp
bug.cpp(11): warning #1125: function "A::foo()" is hidden by "B::foo" -- virtual function override intended?
    void foo(int) {}
         ^

sptel15-671> g++ -c -Woverloaded-virtual bug.cpp
bug.cpp:5:16: warning: virtual void A::foo() was hidden [-Woverloaded-virtual]
   virtual void foo() {}
                ^~~
bug.cpp:11:8: warning:   by void B::foo(int)[-Woverloaded-virtual]
   void foo(int) {}
        ^~~
sptel15-672>

sptem26-34> clang -c -Woverloaded-virtual bug.cpp
bug.cpp:11:8: warning: 'B::foo' hides overloaded virtual function
      [-Woverloaded-virtual]
  void foo(int) {}
       ^
bug.cpp:5:16: note: hidden overloaded virtual function 'A::foo' declared here:
      different number of parameters (0 vs 1)
  virtual void foo() {}
               ^
1 warning generated.
sptem26-35>


This remark is described here:

http://stackoverflow.com/questions/9995421/gcc-woverloaded-virtual-warnings

It only makes sense to give the diagnostic for virtual functions since they are only

useful when you have declared the same routine in both the base and derived class and
you want the "right" version to be called at runtime based upon the actual type of the
object.

I think the remark still makes sense even in some situations where the virtual function is declared private.

Consider this example - the user would probably want to know that the call to a->foo()
through a B pointer is not actually calling a version of foo() in the B class because
they haven't declared one.

#include <stdio.h>

'

struct A {
  void f(A* a)
   { printf("in A::f\n"); a->foo(99); } // Does this call B::foo(long) or A::foo(int)?
private:
  virtual void foo(long) { printf("in A::foo(long)\n");}
  virtual void foo(int) { printf("in A::foo(int)\n");}
};

struct B : public A {
private:
  void foo(long) { printf("in B::foo(long)\n");}
};

int main() {
   A a;
   B* bp = new B;
   a.f(bp);
   return 0;
}

Judy

0 Kudos
olzhas_r_
New Contributor I
1,237 Views

You are right, Judy. This warning is coming from -Wextra.

I think the compiler(s) are being conservative in this case since it is not about "overriding".

Your examples demonstrate overriding but not hiding, in other words, the function signatures are the same. I'd rather expect a warning about "you are missing an 'override' keyword" for these examples.

I believe this case is technically "hiding" because the access specifier is checked after the name lookup, so strictly, this warning is probably not a false positive.

On the other hand, from the user point of view, this warning is negative, and the only thing I get is "rename the conflicting function because one naughty ancestor booked the name in its private parts".

0 Kudos
Judith_W_Intel
Employee
1,237 Views

 

Yes I agree with you but I don't think this is ever going to be a high enough exposure/priority to make the effort of trying to tune the diagnostic... you can always us a command line option or add a #pragma to suppress the remark in this particular case... it's certainly harmless...

0 Kudos
Reply