Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 331 Vote(s) - 3.57 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Why is it possible to declare a struct and a non-struct with the same name?

#1
Apparently,

> For reasons that reach into the prehistory of C, it is possible to declare a struct and a non-struct with the same name in the same scope. - (*Bjarne Stroustrup - The C++ Programming Language. 4th Edition*)

For example:

struct Ambig {};

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

I'm just curious what the initial reason was? Without understanding, it seems like an example of bad language design, that causes ambiguity and is confusing.
Reply

#2
Well adding `struct` before structs is perfectly legal C. Therefore some C code also applies to C++.<br/> What did you expect? C++ is based on C.

In c++ we avoid using `struct` before every struct. I've never actually seen it in production code.

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

#3
>I'm just curious what the initial reason was? Without understanding, it seems like an example of bad language design, that causes ambiguity and is confusing.

In C it's a first implementation of name spaces. Identifiers live in different name spaces and the idea is they can have the same name if they are declared in different name spaces.
Name space for structure tags and ordinary identifiers are not the only two name spaces in C. There are four name spaces in C:

>(C99, 6.2.3 Name spaces of identifiers p1) "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 any24)
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 the
member via the . or -> operator);

>— all other identifiers, called ordinary identifiers (declared in ordinary declarators or as enumeration constants)."
Reply

#4
The reason, as stated in your quote from Stroustrup, is
historical. In C, you _must_ always prefix the name of the
struct with `struct`; the name of the struct (like the name of
unions or enums) is called a tag, and lives in a completely
different name space than other symbols. So things like:

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

are perfectly legal. (The above is, in fact, part of Posix).

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

struct MyClass {};
MyClass variableName;

This would not be legal C. In C, the second line would have to be:

struct MyClass variableName;

The problem is that C++ needs to be able to use interfaces
defined in C (like the Posix interface, above). So C++ defines
some special rules to allow it: you can give a variable or
a function and a class type the same name. When you do, the
variable or function name has precedence, and hides the class
name, except in "elaborated type specifiers" (i.e. `class`,
`struct`, `union` or `enum`, followed by a symbol), where
non-type names are ignored in the lookup.

Reply

#5
The reason it is like this has to do with C++ inheriting from C. It was not "added" to C++, it is there because it works that way in C.

In C, you have to use `struct X` and `union Y` (there is no `class` keyword in C), or use `typedef struct X A;` and then use the name `A` instead of `strcut X` (where X and A could be the same name).

In C++ the compiler will, as long as the name is unique, understand that `X` is referring to `struct X`. You don't have 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 (wherever possible) the use of C syntax, it is still allowed to write `struct X` when referring to a struct. This allows the use of a name that is otherwise ambiguous.

It is highly recommended to NOT make use of this "possibility" unless required by historical design decisions, because all it will achieve is more confusion...
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through