zrozumienie przestrzeni nazw C
Cytowanie z tutaj ,
W języku C istnieją dwie różne przestrzenie nazw typów: przestrzeń nazw nazw znaczników struct/union / enum oraz przestrzeń nazw typów typedef.
Nazwisko.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
$
Próbuję zrozumieć konflikty przestrzeni nazw C.
W pierwszym przypadku, dlaczego jest konflikt? Czy funkcje również należą do przestrzeni nazw typedef?
W drugim przypadku, dlaczego jest nie ma żadnego konfliktu? Zarówno funkcja, jak i zmienna mają nazwę four. Dlaczego kompilator na to pozwala? Jak to ma być rozwiązane?
3 answers
C ma cztery różne przestrzenie nazw dla identyfikatorów:
- nazwy etykiet (typ
goto
). - Tagi (nazwy struktur, związków i wyliczeń).
- Członkowie struktur i związków (mają one oddzielną przestrzeń nazw dla danej struktury/związku).
- wszystkie inne identyfikatory(nazwy funkcji, nazwy obiektów, nazwy typu (def), stałe wyliczenia itp.).
Więc na twoje dwa pytania można odpowiedzieć jako:
- Tak, Funkcja nazwy i nazwy typedef mają tę samą przestrzeń nazw.
- Brak konfliktu, ponieważ kompilator będzie używał reguł zakresu (dla nazw funkcji lub obiektów). Identyfikator w main to shadow globalna nazwa funkcji, o czym Twój kompilator będzie Cię ostrzegał, jeśli ustawisz poziomy ostrzeżeń wystarczająco wysoko.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-25 13:31:20
Ale kluczowym punktem w Twoich przykładach nie jest Przestrzeń nazw, ale zakres nazw.
W nazwie.c , oba long2
są "zwykłymi identyfikatorami" (mają tę samą przestrzeń nazw), a oba są zdefiniowane w tym samym zakresie, więc istnieje konflikt. (C99 §6.7 / 3)
If nazwa2.c, zmienna lokalna four
znajduje się w zakresie głębszym niż funkcja four
, więc zmienna ukrywa funkcję four
(C99 §6.2.1/4).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-25 13:34:54
Twój drugi przykład nie pokazuje "brak konfliktu". Jest konflikt! Spróbuj tego:
#include <stdio.h>
int four(void) { return 4; }
struct dummy { int member; };
int main(void) {
struct dummy four;
four.member = four();
}
A teraz to
#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 */
}
W twoim drugim przykładzie zmienna four
ukrywa funkcję four()
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-29 09:22:39