type namespace in C - c

I've read in SO about different namespaces in C where the type are defined, e.g. there is a namespace for Structs and Unions and a namespace for typedefs.
Is namespace the exact name for this? How many namespaces exist in C?

see 6.2.3
from http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
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).

I am not sure if "namespace" is the right word here, but I think I know what you mean.
You can do
union name1 { int i; char c; };
struct name2 { int i; char c; };
enum name3 { A, B, C };
typedef int name4;
int name5;
Here name1, name2 and name3 are in distinct "namespaces" (I'll keep that word for now), as they don't collide with each other.
This implies that using them requires to prefix their use with the respective keyword:
struct name1 var; // valid
name1 var; // invalid
On the other hand, name4 and name5 live in the global "namespace" and collide. So after having typedef int name4;, you cannot define a variable with that name name4.
BTW: The labels as well define their own namespace.

Related

Some questions about struct namespace in C

I'm trying to understand this answer - typedef struct vs struct definitions [duplicate]:
(Line 3): ["] In the first line you are defining the identifier S within the struct name space (not in the C++ sense). [."]
It seems like for struct X {...};, the {...} is like an adjective for X, and X {...} is thrown into something called struct-namespace, how many struct-namespace are there in a program? Is there only one specified by struct?
It seems like in C/C++ struct and class are almost the same? So in C++ struct and class are both in class-namespace?
From the C99 standard draft
6.2.3
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 namespaces
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
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).
In other words, if you have struct S, then S is in the struct namespace, whereas if you have int S as well, then it's in the namespace of ordinary identifiers.
This is not the case for C++
1 (for C): there is one namespace for all structure tags. You can have as many different tags as you want, even if the same name is used in other namespaces.
Each structure on its own is its own namespace (there are "infinite" struct namespaces).
// You can have
struct foo { int var; }
struct bar { double var; }
struct baz { int var; }
struct qux { int var; }
// with no conflict between all the `var`

Namespaces in C formal definition

I'm reading the N1570 Standard and have a problem to understand the wording of the name space definition. Here is it:
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).
32) There is only one name space for tags even though three are possible.
Here they are talking about in case of more than 1 declaration of particular identifiers is visible. Now words something like "To access an identifier one shall specify its namespace" or "To access an identifier in a specific namespace...".
Let me show an example first (this is strictly for understanding purpose, dont write code like this, ever)
#include <stdio.h>
int main(void)
{
int here = 0; //.......................ordinary identifier
struct here { //.......................structure tag
int here; //.......................member of a structure
} there;
here: //......... a label name
here++;
printf("Inside here\n");
there.here = here; //...........no conflict, both are in separate namespace
if (here > 2) {
return 0;
}
else
goto here; //......... a label name
printf("Hello, world!\n"); // control does not reach here..intentionally :)
return 0;
}
You see usage of identifier here. They belong to separate namespace(s) according to the rule, hence this program is fine.
However, say, for example, you change the structure variable name, from there to here, and you'll see a conflict, as then, there would be two separate declaration of same identifier (ordinary identifier) in the same namespace.

Why doesn't the compiler give a conflicting error?

In following code, I have declared a structure member variable as a same name of structure name.
struct st
{
int st;
};
int main()
{
struct st t;
t.st = 7;
return 0;
}
I wonder, it's working fine on GCC compiler and doesn't give a conflict error.
So,
How does the compiler know structure name and variable name?
What mechanism compiler internally use?
Yes, it's valid. The struct tag and the struct members are in different namespace.
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 name of the structure type is struct st. Not just st, so there's no conflict at all.

Typedef and enum with same name?

In the library FreeImagePlus, in FreeImage.h, there is a funny #define which seems to create a typedef and an enum with the same name:
#define FI_ENUM(x) typedef int x; enum x
This is expanded by the preprocessor to code like:
typedef int FREE_IMAGE_FILTER;
enum FREE_IMAGE_FILTER {
FILTER_BOX = 0,
FILTER_BICUBIC = 1,
[...]
What does this do? Is it even legal to have a typedef and an enum with the same name?
And isn't an enum compatible to int anyway? Why does FreeImage do this?
Names of structures, unions and enumerations lives in their own namespace. That's why you can declare a struct/union/enum variable with the same name as the actual struct/union/enum.
And it's not the name of the complete enum (e.g. for enum X I mean the X) that has to be compatible with an integer, it's the names inside the enumeration.
Quoting C99 N1256 draft 6.2.1 "Scopes of identifiers":
An identifier can denote an object; a function; a tag or a member of a structure, union, or enumeration; a typedef name; a label name; a macro name; or a macro parameter.
which means that in:
typedef int id;
id is an identifier.
And from 6.2.3 "Name spaces of identifiers":
BEGIN QUOTE
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 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).
END QUOTE
So in:
typedef int id;
enum id {ID0};
the first id is an ordinary identifier
the second is a tag identifier
an both can coexist pacifically.
On the other hand, we could not do something like:
typedef int id;
int id;
because both would be ordinary identifiers.

In C, can struct members use the same name as a type?

For example, is the following valid C code?
typedef struct {
/* ... */
} foo;
typedef struct {
foo foo; /* Is it ok that 'foo' == 'foo'? */
} bar;
Yes that is valid C (although it is not readable and should be avoided).
Types identifiers and struct members identifiers live in different name spaces.
See C99, 6.2.3p1 Name spaces of identifiers:
[...] 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 [...]
— the members of structures or unions; each structure or union has a separate name
space for its members [...]
— all other identifiers, called ordinary identifiers [...]

Resources