简体   繁体   中英

Definition of class and variable with the same name

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM