This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: C++: INHERITED_VALUE_BINDING_P
Mark Mitchell <mark@codesourcery.com> writes:
| On Thu, 2003-10-23 at 06:09, Gabriel Dos Reis wrote:
| > Hi,
| >
| > In the C++ front-end, the macro INHERITED_VALUE_BINDING_P is used to
| > distinguish a class-scope declaration that is inherited (from a base
| > class) from regular ones. I believe that is a carry-over from old ARM
| > scope rules. I think we could safely get rid of it because standard
| > scope notions make no room for the idea of inherited declaration:
| > Instead, each base class retains its scope and declarations in derived
| > class hide declarations in base classes.
|
| IIRC, this is not quite true.
3.3.7/1 says:
A name can be hidden by an explicit declaration of that same name in
a nested declarative region or derived class (10.2).
3.3.7/3
[...] The declaration of a member in a derived class (clause 10)
hides the declaration of a member of a base class of the same name;
see 10.2.
| In particular, this code:
|
| struct A {
| struct B {};
| };
|
| struct C : public A {
| void B();
| };
|
| struct C::B b;
|
| is legal.
I do not believe the program is well-formed for the reasons explained
in 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 sub-object 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 declara-tion
designated by the using-declaration. 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.
But what I wanted to express is this:
struct A {
void f(int);
};
struct B : A {
void f(double);
};
The f declared in B is NOT an overload of A::f: Rather it hides A::f.
Put different, the following is ill-formed:
void (B::*pmf)(int) = &B::f;
| That's the case where INHERITED_VALUE_BINDING_P is used, I
| think.
I think that even for the purpose of distinguishing a non-type name
from a type-name, we can use the trick as we do for the following:
struct stat { };
struct stat stat(int);
struct stat s = stat(89);
-- Gaby