2010-09-25 7 views
15

Citando here,la comprensión de los espacios de nombres C

En C, hay dos espacios de nombres diferentes de tipos: un espacio de nombres de unión/nombres de las etiquetas struct/ENUM y un espacio de nombres de nombres typedef.

name.c

$ cat name.c 
#include<stdio.h> 

typedef long long long2; 

int long2() { 
    return 4; 
} 

int main() { 

    printf("hello, world!"); 
    return 0; 
} 
$ gcc name.c -o name 
name.c:4: error: 'long2' redeclared as different kind of symbol 
name.c:3: error: previous declaration of 'long2' was here 
$ 

name2.c

$ cat name2.c 
#include<stdio.h> 

int four() { 
    return 4; 
} 

struct dummy { 
    int member; 
}; 

int main() { 

    struct dummy four; 
} 

$ gcc name2.c -o name2 
$ 

Estoy tratando de entender los conflictos de espacio de nombres C.

  • En el primer caso, ¿por qué hay un conflicto? ¿Las funciones también pertenecen al espacio de nombres typedef?

  • En el segundo caso, ¿por qué no hay ningún conflicto? La función y la variable se nombran cuatro. ¿Por qué el compilador lo permite? ¿Cómo se supone que se resuelve &four?

Respuesta

20

C tiene cuatro espacios de nombres diferentes para identificadores:

  • Los nombres de etiqueta (el tipo goto).
  • Etiquetas (nombres de estructuras, uniones y enumeraciones).
  • Miembros de estructuras y uniones (estos tienen un espacio de nombres separado por estructura/unión).
  • Todos los demás identificadores (nombres de funciones, nombres de objetos, nombres de tipo (def), constantes de enumeración, etc.).

Véase también C99 6.2.3.

Así sus dos pregunta puede responderse como:

  1. Sí, los nombres de funciones y nombres typedef comparten el mismo espacio de nombre.
  2. Sin conflicto, porque el compilador usará reglas de alcance (para los nombres de funciones o objetos). El identificador en main se dice shadow el nombre de la función global, algo sobre lo que el compilador le advertirá si establece los niveles de advertencia lo suficientemente altos.
+0

¿Las estructuras/uniones/enums comparten un espacio de nombre? es decir, ¿'struct T' y' union T' van bien juntas? – iBug

5

Su segundo ejemplo no muestra "sin conflicto". Hay un conflicto! Prueba esto:

#include <stdio.h> 
int four(void) { return 4; } 
struct dummy { int member; }; 
int main(void) { 
    struct dummy four; 
    four.member = four(); 
} 

Y ahora esto

#include <stdio.h> 
int four(void) { return 4; } 
struct dummy { int member; }; 
int main(void) { 
    int (*fx)(void) = four; /* "save" function */ 
    struct dummy four;  /* hide it   */ 
    four.member = fx(); /* use "hidden" fx */ 
} 

En el segundo ejemplo, la variable fourcueros la función four().

6

Pero el punto crucial en sus ejemplos no es sobre el espacio de nombres, sino el alcance de los nombres.

En name.c, tanto long2 son "identificadores ordinarios" (compartir el mismo espacio de nombres), y ambos de ellos se definen en el mismo alcance, así que hay un conflicto. (C99 § 6,7/3)

Si name2.c, la variable local four está en un alcance más profundo que la función four, por lo que las variables cueros la función four (C99 § 6.2.1/4) .

Cuestiones relacionadas