There is this code:
int x;
//void x(); // error: redefinition of 'x' as different kind of symbol
class x {}; // works ok
int main() {
return 0;
}
Why is it legal to define variable and class with the same name but it is not legal to define variable and function with the same name?
First Case: 2 Identifiers
int x;
void x();
Second Case: 1 Identifier, 1 Typename
int x;
class x {};
The compiler can't handle the first case because you have 2 identifiers with the same name, so there could be an ambiguity. (Example: Try getting the memory address of one of them. That's one case where an ambiguity could arise)
The compiler can handle the second case because one is a type and the other is an identifier, and because it knows where to expect a type and where to expect an identifier, there is no ambiguity.
This is needed for backward-compatibility with C (if I recall, some UNIX headers define both a struct and a variable with the same name).
You can disambiguate between a class and a variable/function:
int x;
class x {};
int main()
{
x = 42; // global int x
//x obj; // error
class x obj; // use class-tag to disambiguate
}
But you cannot disambiguate between a variable and a function.
See also the book "The Design and Evolution of C++" by Bjarne Stroustrup, §2.8.2.
What's going on here is specific to C++. The use of x
as a class name is hidden.
Section 3.3.7 (Name Hiding) paragraph 2:
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.
union
, enum
and struct
(and I suppose class
too) together have seperate "name buckets" (has nothing to do with C++ namespaces!) from ordinary identifiers. This becomes clear in C, because you have to prefix the names with struct
etc.
I don't have it for C++, but this is from the C standard:
6.2.3 Name spaces of identifiers
If more than one declaration of a particular identifier is visible at
any point in a translation unit, the syntactic context disambiguates uses
that refer to different entities.
Thus, there are separate name spaces for various categories of identifiers,
as follows:
— label names (disambiguated by the syntax of the label declaration and use);
— the tags of structures, unions, and enumerations (disambiguated by
following any32) of the keywords struct, union, or enum);
— the members of structures or unions; each structure or union has a
separate name space for its members (disambiguated by the type of the
expression used to access themember via the . or -> operator);
— all other identifiers, called ordinary identifiers (declared in ordinary
declarators or as enumeration constants).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.