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?

Author: Community, 2010-09-25

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.).
Zob. również C99 6.2.3.

Więc na twoje dwa pytania można odpowiedzieć jako:

  1. Tak, Funkcja nazwy i nazwy typedef mają tę samą przestrzeń nazw.
  2. 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.
 22
Author: schot,
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).

 6
Author: kennytm,
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().

 5
Author: pmg,
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