Cuando se encuentra un identificador en un programa C, se realiza una búsqueda para ubicar la declaración que introdujo ese identificador y que está actualmente dentro del alcance. C permite que más de una declaración para el mismo identificador esté dentro del alcance simultáneamente si estos identificadores pertenecen a diferentes categorías, llamadas espacios de nombres:

1) Espacio de nombres de etiquetas: todos los identificadores declarados como etiquetas.2) Nombres de etiquetas: todos los identificadores declarados como nombres de estructuras, uniones y tipos enumerados. Tenga en cuenta que los tres tipos de etiquetas comparten un espacio de nombre.3) Nombres de miembros: todos los identificadores declarados como miembros de cualquier estructura o unión. Cada estructura y unión introduce su propio espacio de nombres de este tipo.4) Todos los demás identificadores, llamados identificadores ordinarios para distinguir de (1-3) (nombres de funciones, nombres de objetos, nombres typedef, constantes de enumeración).

En el momento de la búsqueda, el espacio de nombres de un identificador está determinado por la forma en que se utiliza:

1) El identificador que aparece como el operando de una instrucción goto se busca en el espacio de nombres de la etiqueta.2) identificador que sigue a la palabra clave struct, uniono enum se busca en el espacio del nombre de la etiqueta.3) El identificador que sigue al acceso a miembros o al acceso a miembros a través del operador de puntero se busca en el espacio de nombres de los miembros del tipo determinado por el operando de la izquierda del operador de acceso a miembros.4) todos los demás identificadores se buscan en el espacio de nombres de los identificadores ordinarios.

notas

Los nombres de las macros no forman parte de ningún espacio de nombres porque son reemplazados por el preprocesador antes del análisis semántico.

Es una práctica común inyectar nombres de estructura/unión/enumeración en el espacio de nombres de los identificadores ordinarios mediante una declaración typedef:

structA;// introduces the name A in tag name spacetypedefstructA A;// first, lookup for A after "struct" finds one in tag name space// then introduces the name A in the ordinary name spacestructA* p;// OK, this A is looked up in the tag name space
A* q;// OK, this A is looked up in the ordinary name space

Un ejemplo bien conocido del mismo identificador que se usa en dos espacios de nombres es el identificador stat del encabezado POSIX sys/stat.h. Eso nombra una función cuando se utiliza como un identificador ordinario y indica una estructura cuando se usa como una etiqueta.

A diferencia de C++, las constantes de enumeración no son miembros de estructura, y su espacio de nombres es el espacio de nombres de los identificadores ordinarios, y dado que no hay un alcance de estructura en C, su alcance es el alcance en el que aparece la declaración de estructura:

structtagged_unionenumINT, FLOAT, STRING type;int integer;float floating_point;char*string; tu;
 
tu.type = INT;// OK in C, error in C++

Ejemplo

voidfoo(void)return;// ordinary name space, file scopestructfoo// tag name space, file scopeint foo;// member name space for this struct foo, file scopeenumbar// tag name space, file scope
        RED       // ordinary name space, file scope bar;// member name space for this struct foo, file scopestructfoo* p;// OK: uses tag/file scope name "foo";enumbar x;// OK: uses tag/file-scope bar// int foo; // Error: ordinary name space foo already in scope //union foo  int a, b; ; // Error: tag name space foo in scopeintmain(void)goto foo;// OK uses "foo" from label name space/function scopestructfoo// tag name space, block scope (hides file scope)enumbar x;// OK, uses "bar" from tag name space/file scope;typedefstructfoo foo;// OK: uses foo from tag name space/block scope// defines block-scope ordinary foo (hides file scope)(foo).x=RED;// uses ordinary/block-scope foo and ordinary/file-scope RED
 
foo:;// label name space, function scope

Referencias

  • Estándar C11 (ISO/IEC 9899:2011):
    • 6.2.3 Espacios de nombres de identificadores (p: 37)
  • Norma C99 (ISO/IEC 9899:1999):
    • 6.2.3 Espacios de nombres de identificadores (p: 31)
  • Estándar C89/C90 (ISO/IEC 9899:1990):
    • 3.1.2.3 Espacios de nombres de identificadores

Ver también