Why can you declare a structure and non-structure with the same name?

Apparently

For reasons that go back to C, you can declare a structure and non-structure with the same name in the same scope. - (Bjarne Stroustrup - C ++ programming language. 4th edition)

For instance:

struct Ambig {}; // the struct must be referred to with the prefix struct void Ambig(struct Ambig* buf) {} 

I'm just wondering what was the original reason? Without understanding, this is like a poor language design that is ambiguous and confusing.

+6
source share
4 answers

The reason, as indicated in your quote from Straustrup, is historical. In C, you should always specify the name struct with struct ; the name of the structure (for example, the name of unions or enumerations) is called a tag and lives a completely different namespace than other characters. So things like:

 struct stat { // ... }; int stat( char const* filename, struct stat* buf ); 

are completely legal. (This is, in fact, part of Posix).

In C ++, a class name (declared using class , struct or union ), or an enumeration is in the same namespace as everything else, and unlike C, you can write things like:

 struct MyClass {}; MyClass variableName; 

This will not be legal C. In C, the second line should be:

 struct MyClass variableName; 

The problem is that C ++ should be able to use interfaces defined in C (for example, the Posix interface, above). Therefore, C ++ defines some special rules that allow this: you can specify a variable or function and the class type has the same name. When you do this, the name of the variable or function takes precedence and hides the class name, with the exception of “specified type specifiers” (ie class , struct , union or enum followed by a character), where non-type names are ignored when searching .

+6
source

The reason this happens is because C ++ inherits from C. It has not been “added” to C ++, it exists because it works this way in C.

In C, you must use struct X and union Y (C does not have the class keyword) or use typedef struct XA; and then use A instead of strcut X (where X and A can be the same name).

In C ++, the compiler will, if the name is unique, understand that X refers to struct X You do not need to type struct , union or class in front of the name or use typedef to create a new standalone name.

Since C ++ is designed to allow (when possible) the use of C syntax, it is still allowed to write struct X when accessing the structure. This allows you to use a name that is otherwise ambiguous.

It is highly recommended that you DO NOT use this “opportunity” if it is not required by historical design decisions, because everything that it achieves is more confused ...

+3
source

I'm just wondering what was the original reason? Without understanding, this is like a poor language design that is ambiguous and confusing.

In C, this is the first implementation of namespaces. Identifiers live in different namespaces, and the idea is that they can have the same name if they are declared in different namespaces. The namespace for structure tags and common identifiers is not only two namespaces in C. There are four namespaces in C:

(C99, 6.2.3 Identification spaces of identifiers p1) "Thus, there are separate namespaces for different categories of identifiers, as shown below:

- label names (ambiguous syntax for declaration and use of labels);

- tags of structures, associations and enumerations (ambiguously following any 24) keywords of struct, union or enum);

- members of structures or unions; each structure or association has a separate namespace for its members (ambiguous in the type of expression used to access the member through. or →);

- all other identifiers called regular identifiers (declared in ordinary declarators or as enumeration constants).

+2
source

Well, adding a struct before the structures are completely legal C. Therefore, some C code is also applicable to C ++.
What did you expect? C ++ is based on C.

In C ++, we avoid using a struct before each structure. I have never seen it in production code.

As for the ambiguity, I don't think anyone knows why they allow it. But I believe, because the ambiguity is resolved when you add a struct . You essentially tell the compiler that this is not a function, and therefore the possible meaning eliminated.

+1
source

Source: https://habr.com/ru/post/951788/


All Articles