This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Bug: name lookup ambiguities in class scope
- To: <gcc-bugs at gcc dot gnu dot org>
- Subject: Bug: name lookup ambiguities in class scope
- From: "Carlos Pita" <cpitaar at yahoo dot com dot ar>
- Date: Wed, 18 Jul 2001 09:22:35 -0300
g++ 3.0 compiles (with -pedantic) the following code without complaining.
But according to the ISO standard (final, not the draft) the program is
ill-formed because of #1 and #2 (marked in the comments):
struct A {
void f(int) {};
void f(char) {};
};
struct B {
void f(double);
};
struct C:public A,B {
using A::f;
using B::f;
void g() { f(1); }; // <-- this shouldn't work (#1)
};
struct D:public A,B {
using A::f;
void g() { f(1); }; // <-- this shouldn't work (#2)
};
struct E:public A,B {
using A::f;
using B::f;
void f(int) {};
void g() { f(1); }; // <-- this is fine
};
struct F:public A,B {
using A::f;
void f(int) {};
void g() { f(1); }; // <-- this is fine
};
int main() {
C c;
D d;
E e;
F f;
//...
return 0;
}
The related standard sections are 10.2.2, 7.3.3.12 and 7.3.3.13. I'm
partially quoting them below:
"""
10.2.2 The following steps define the result of name lookup in a class
scope, C. First, every declaration for the name in the class and in each
of its base class sub-objects is considered. A member name f in one
subobject B hides a member name f in a sub-object A if A is a base class
sub-object of B. Any declarations that are so hidden are eliminated from
consideration. Each of these declarations that was introduced by a
using-declaration is considered to be from each sub-object of C that
is of the type containing the declaration designated by the
using-declaration.*96*) If the resulting set of declarations are not all
from sub-objects of the same type, or the set has a nonstatic member and
includes members from distinct sub-objects, there is an ambiguity and the
program is ill-formed. Otherwise that set is the result of the lookup.
Note *96* says: Note that using-declarations cannot be used to resolve
inherited member ambiguities...
7.3.3.12 When a using-declaration brings names from a base class into a
derived class scope, member functions in the derived class override
and/or hide member functions with the same name and parameter types in
a base class (rather than conflicting). [Example....
7.3.3.13 For the purpose of overload resolution, the functions
which are introduced by a using-declaration into a derived class will be
treated as though they were members of the derived class.
"""
Following 10.2.2 neither A::f nor B::f is hidden by a declaration of a
member f in C so there is an ambiguity in the body of C::g. The same can be
said for D. The ambiguity is eliminated in E and F because of the
declarations of E::f and F::f respectively. Then, according 7.3.3.12 and
7.3.3.13, overloading will be done for E::f in order to select one function
from the set {A::f(char), B::f(double), E::f(int)}. Similarly, the set for
F::f will be {A::f(char), B::f(double), F::f(int)}. So classes E and F don't
make the program ill-formed.
I'll submit this as a bug 5 days after posting it here except in case that
anyone of you think (and convincingly explain why :) ) this is not a bug
before the fifth day. I prefer some discussion before submitting bugs
related to ISO conformace bacause of the vaguety and complexity that
sometimes obscures the standard text.
See you,
Carlos
_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com