понимание пространств имен C - PullRequest
22 голосов
/ 25 сентября 2010

Цитирование из здесь ,

В C существует два разных пространства имен типов: пространство имен имен тегов struct / union / enum и пространство имен имен 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
$ 

Я пытаюсь понятьКонфликты пространства имен C.

  • В первом случае, почему возникает конфликт?Функции также принадлежат пространству имен typedef?

  • Во втором случае, почему вообще нет конфликта?Функция и переменная называются четыре.Почему компилятор позволяет это?Как разрешить &four?

Ответы [ 3 ]

26 голосов
/ 25 сентября 2010

C имеет четыре разных пространства имен для идентификаторов:

  • Имена меток (тип goto).
  • Теги (названия структур, союзов и перечислений).
  • Члены структур и объединений (у них есть отдельное пространство имен для структуры / объединения).
  • Все остальные идентификаторы (имена функций, имена объектов, имена типов (def), константы перечисления и т. Д.).

См. Также C99 6.2.3.

Итак, на ваш вопрос можно ответить так:

  1. Да, имена функций и имена typedef имеют одинаковое пространство имен.
  2. Нет конфликта, потому что компилятор будет использовать правила области видимости (для имен функций или объектов). Идентификатор в main называется shadow глобальным именем функции, о чем ваш компилятор будет предупреждать вас, если вы установите достаточно высокие уровни предупреждений.
7 голосов
/ 25 сентября 2010

Но критический момент в ваших примерах - не пространство имен, а область имен.

В name.c оба long2 являются "обычными идентификаторами" (использовать одно и то же пространство имен), и оба они определены в одной и той же области видимости, поэтому возникает конфликт.(C99 §6.7 / 3)

Если name2.c , локальная переменная four находится в области видимости глубже функции four, поэтому переменная скрывается функция four (C99 §6.2.1 / 4).

6 голосов
/ 25 сентября 2010

Ваш второй пример не показывает "нет конфликта". Есть конфликт! Попробуйте это:

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

А теперь это

#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 */
}

Во втором примере переменная four скрывает функцию four().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...