Defining a 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 legitimate to define a variable and a class with the same name, but is it not legal to define a variable and a function with the same name?

+7
source share
4 answers

What happens here is typical of C ++. Using x as the class name is hidden.

Section 3.3.7 (Concealment of Name), Clause 2:

The name of the class (9.1) or the name of the enumeration (7.2) can be hidden by the name of the object, function or enumeration 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 type of object, function or counter name is.

+5
source

First case: 2 identifiers

 int x; void x(); 

Second case: 1 Identifier, 1 File_name

 int x; class x {}; 

The compiler cannot handle the first case, because you have 2 identifiers with the same name, so there may be ambiguity. (Example: try to get the memory address of one of them. This is a case where ambiguity may occur)

The compiler can handle the second case, because one is a type and the other is an identifier, and since it knows where to expect a type and where to expect an identifier, there is no ambiguity.

+13
source

This is necessary for backward compatibility with C (if I recall, some UNIX headers define both a structure and a variable with the same name).

You can eliminate the ambiguity between the class and the 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 eliminate the ambiguity between a variable and a function.

See also the book Design and Evolution of C ++ by Bjarna Straustrup, Β§2.8.2.

+4
source

union , enum and struct (and I believe that class too) together have separate "name buckets" (which have nothing to do with C ++ namespaces!) from common identifiers. This becomes understandable in C because you must prefix the names with struct , etc.

I don't have one 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). 
+2
source

All Articles