0
votes

I know how namespaces work in C++, but I´m a little bit confused of how they work in C. So, I did a bit of research about name spaces in C.

First, the respective section in ISO/IEC 9899:2018 (C18), section 6.2.3:

6.2.3 Name spaces of identifiers

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 any(32)) 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).


32) There is only one name space for tags even though three are possible.

So this gives me a bit more understanding of the term in C and seems to generally have the same kind of purpose as in C++. But unfortunately, there is nothing further said in the standard about how name spaces work in C.

Apparently, it has something to do with the distinction between entities that share the same identifier and, as opposed to C++, where we declaring namespaces like:

namespace ctrl1 
{ 
    int max = 245; 
} 

and using namespaces, like:

using namespace ctrl1;

or

int a = ctrl1::max;

in C, the compiler is be able to disambiguate a certain use of one object automatically if the respective identifier is used. Correct me, if I´m wrong.

How does that work? How does the compiler know if he shall use one entity instead of the other in C?


I have read Name spaces in c++ and c but the question is more focused on C++ and focused on the handling of a specific example.

I also read the Name spaces in C where again the purpose of the question is more focused on a specific example, here the enum type.


My Question is:

  • How do name spaces work in C?
1
The quote explains it quite well I think. A label is a label. It can’t be anything else and it can only appear where labels do, followed by colon or after goto, for example. A struct member cannot again be anything else. strut.val or strut->val can’t be anything else than a member of that specific struct. The language syntax is unambiguous about these.Sami Kuhmonen
Namespaces in C++ provide a way for the programmer to control disambiguation of identifiers. There is no such mechanism in C. Other than that, the reference you cited is pretty straightforward about how namespaces intersect in C.Mark Benningfield
@SamiKuhmonen How can a label be used for two or more entities?RobertS supports Monica Cellio
@MarkBenningfield the syntactic context disambiguates uses that refer to different entities - How is the syntactic context able to disambiguate?RobertS supports Monica Cellio

1 Answers

8
votes

in C, the compiler is be able to disambiguate a certain use of one object automatically if the respective identifier is used. Correct me, if I´m wrong.

How does that work? How does the compiler know if he shall use one entity instead of the other in C?

The excerpt from the standard already addresses this (emphasis added):

— label names (disambiguated by the syntax of the label declaration and use);

A label declaration has the form of an identifier followed by a colon, which must be followed by a statement:

a_label:
do_something;

The only use of labels is in goto statements, and the identifier in a goto statement can be only a label:

goto a_label;

— the tags of structures, unions, and enumerations (disambiguated by following any32) of the keywords struct, union, or enum);

"Following any of the keywords struct, union, or enum" means exactly what it says:

struct a_tag
union another_tag
enum a_third_tag

Those forms can appear in type definintions, type declarations, and type uses. If one of the keywords struct, union, or enum immediately precedes an identifier then that identifier is a tag; otherwise it isn't.

— 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);

The appearance of an identifier as the right-hand operand of a . or -> operator distinguishes it as the identifier of a structure or union member. The type of the left-hand operand determines of which structure or union type. C structure and union types cannot have static members, so there is never any need to access a structure or union member relative to the type itself, absent an object of that type.

all other identifiers, called ordinary identifiers

Anything not covered by one of the other three cases is covered by this one. That includes variable names, function names, function parameter names, built-in and typedefed type names, and enumeration constants. (I think that's a complete list, but I may have overlooked something).

  • How do name spaces work in C?

The only other thing I can think of to clarify is that unlike in C++, C has only implicit declaration and use of namespaces. There is no namespace keyword in C, and no syntax for explicitly referring to an identifier relative to a chosen namespace. User-defined namespaces being limited to those associated with structure and union types, the simple, implicit approach satisfactorily covers all possible cases.

Given that the category of ordinary identifiers is very broad, however, it has become conventional for authors of reusable C libraries to minimize the likelihood of name collisions by prefixing the external identifiers exposed by their libraries with characteristic short prefixes. This ad hoc namespacing is quite outside the scope of the standard, but very common.