Alf P. Steinbach wrote:
* Greg Herlihy: Yan wrote: Here is the code:
class A {};
void (A::*A) (); // Line 3
int main() {
A a; // Line 6
return 0;
}
If you remove Line 3 everything becomes trivial and compiles. However
with line 3 present Line 6 doesn't compile (on VC++ 7.1) with the
following errors:
error C2146: syntax error : missing ';' before identifier 'a'
error C2065: 'a' : undeclared identifier
Line 3 declares a pointer to member by the name A. I guess it shadows
class A and that's why Line 6 doesn't compile. Why isn't the compiler
complaining about Line 3 instead (with let's say 'redifinition' error)?
I tried Cygwin version of gcc and it fails compiling and also points
out Line 6 as the source of the error.
The A member pointer name does not shadow the A class name, rather it
hides it. Change the A class name to B and the problem becomes more
clear:
class B {};
void (B::*A) (); // Line 3
int main()
{
A a; // Line 6
}
The A on line six is the name of a member pointer - not a class - so "A
a" is a syntax error. And because the two "A"'s are in distinct name
scopes (one is a class and the other an identifier), they do not
conflict - one simply ends up hiding the other.
Well, please, because I'm way too lazy to solve the puzzle, where does
the C++ standard define name scopes such as "class" and "identifier"?
I consulted the grammar summary in Appendix A and came up "class-name"
but no special term for a variable's name - only "identifier". A
class-name is also an identifier - so perhaps "name" or "variable name"
would been a better choice. Especially since §3.1/4 defines a "name"
as "a use of an identifier (2.10) that denotes an entity or label
(6.6.4, 6.1)." §3.1/2 defines "entity" as "a value, object, subobject,
base class subobject, array element, variable, function, instance of a
function, enumerator, type, class member, template, or namespace."
A name therefore is distinct from a user-declared "keyword" which can
be any of a "class-name, enum-name, template-name, typedef-name,
namespace-name, original-namespace-name or a namespace-alias."
(summarized in Appendix A.1)
The formal definition of naming hiding also distinguishes between
different name - here again I probably did not pick the best word to
use (scope) perhaps "category" or "type" - would have been more clear:
"A class name (9.1) or enumeration name (7.2) can be hidden by the name
of an object, function, or enumerator declared in the same scope. If a
class or enumeration name and an object, function, or enumerator are
declared in the same scope (in any order) with the same name, the class
or enumeration name is hidden wherever the object, function, or
enumerator name is visible." §3.3.7/2
Greg
[ See
http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]