Why can typedef'd names be used as the names of struct members?

Members of structures and ordinary variables are in different namespaces. That's why having two ordinary variables with same identifier name fails whereas if the same identifier name is used in a struct member and an ordinary variable is fine.

The C standard defines distinct namespaces:

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 last two bullet items directly address this question)

Yes, typedef'ed identifiers share the name space with ordinary identifiers. 6.7.8 Type definitions:

[...] A typedef name shares the same name space as other identifiers declared in ordinary declarators.

Taken from here: https://www.spinellis.gr/cscout/doc/name.html

C has 4 different namespaces. These are not the namespaces from C++, which are accessed by using the keyword namespace. Rather, these are seperate areas for symbols:

  • Tags for a struct/union/enum

  • Members of struct/union (actually a separate namespace is assigned to each struct/union)

  • Labels

  • Ordinary identifiers (termed objects in the C standard)