Note: this question is about name space
, not namespace
.
The C++ standard has some references to name space
, but I don't see the definition of this. The standards says that labels and macros are in different name spaces. All the other references to name space
are in the C/C++ compatibility section, like this (current draft):
This is one of the few incompatibilities between C and C++ that can be attributed to the new C++ name space definition where a name can be declared as a type and as a non-type in a single scope causing the non-type name to hide the type name and requiring that the keywords class, struct, union or enum be used to refer to the type name. This new name space definition provides important notational conveniences to C++ programmers and helps making the use of the user-defined types as similar as possible to the use of fundamental types.
What is this new name space definition? Where can I find it in the standard? What are the exact rules? The rules seem to be more complicated, than "non-types hide types". Like, this doesn't compile:
typedef int Foo; // Foo is a type
void Foo(); // not a type, but compile error, instead of hiding
But this does:
struct Foo { }; // Foo is a type as well
void Foo(); // This hides the type Foo. "struct Foo" refers to the type
And this doesn't compile either:
struct Foo { }; // Type
namespace Foo { } // Non-type, but compiler error instead of hiding
There four types of namespaces in C#. Directive Namespace: The directive namespace that is from link library and direct as link.
A namespace is a declarative region that provides a scope to the identifiers (the names of types, functions, variables, etc) inside it. Namespaces are used to organize code into logical groups and to prevent name collisions that can occur especially when your code base includes multiple libraries.
In computing, a namespace is a set of signs (names) that are used to identify and refer to objects of various kinds. A namespace ensures that all of a given set of objects have unique names so that they can be easily identified.
A namespace is designed for providing a way to keep one set of names separate from another. The class names declared in one namespace does not conflict with the same class names declared in another.
The name space term may be more well-established in the ISO C Standard; citing ISO C11:
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 the member via the . or -> operator);
- all other identifiers, called ordinary identifiers (declared in ordinary declarators or as enumeration constants).
The new name space definition of C++ is, however, not in any way recent in time, and has been described in [diff.class]/1 in its current form ever since the ISO C++ Standard's introduction in '98. It's only ever mentioned in any length in the contexts for which it differs from ISO C, as per [diff.class]/1 which is quoted by the OP.
Afaics we need to resort to ISO C11/6.2.3 and combine it with [diff.class]/1 of the ISO C++ Standard for a cohesive and complete description of the (new) name space definition of C++, less we scourge the ISO C++ Standard for e.g. [basic.scope.hiding], [class.name]/2, [stmt.label]/1, [cpp.replace]/8 and so on to see how and where it applies.
[class.name]/2
A class declaration introduces the class name into the scope where it is declared and hides any class, variable, function, or other declaration of that name in an enclosing scope. [...]
[stmt.label]/1
[...] Labels have their own name space and do not interfere with other identifiers [...]
[cpp.replace]/1
[...] There is one name space for macro names. [...]
In C (6.2.3 Name spaces of identifiers) the notion of name spaces is defined the following way.
1 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 the member via the . or -> operator);
— all other identifiers, called ordinary identifiers (declared in ordinary declarators or as enumeration constants).
So for example a structure tag name can coincide with a function name because they belong to different name spaces. When you specify a structure with a structure tag name when you have to use the keyword struct
. So for example these declarations do not conflict.
struct s
{
int s;
};
void s( void );
struct s s1;
In this code snippet the tag name s
of the structure does not conflict with the function name s
because the tag name shall be specified with the keyword struct
.
In C++ you are allowed to use structure tag names without the keyword struct
.
For example
struct s
{
int s;
};
s s;
is a correct code. In this declaration
s s;
the name of the declared identifier s
hides the structure name. SO if then you will write for example
s s1;
then the compiler will issue an error because in this statement s is considered as the name of the identifier declared above. To resolve the ambiguity you need to use the keyword struct
struct s
{
int s;
};
s s;
struct s s1;
This is described in the following quote from the C++ 20 Standard (6.3.1 Declarative regions and scopes)
4 Given a set of declarations in a single declarative region, each of which specifies the same unqualified name,
(4.1) — they shall all refer to the same entity, or all refer to functions and function templates; or
(4.2) — exactly one declaration shall declare a class name or enumeration name that is not a typedef name and the other declarations shall all refer to the same variable, non-static data member, or enumerator, or all refer to functions and function templates; in this case the class name or enumeration name is hidden (6.3.10). [ Note: A namespace name or a class template name must be unique in its declarative region (10.3.2, Clause 17). — end note ]
As you can see from the quote a namespace name must be unique in its declarative region. So these declarations
struct Foo { };
namespace Foo { }
are incorrect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With