Понимание пространств имен C
Цитата из здесь,
В 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
?
Ответы
Ответ 1
C имеет четыре разных пространства имен для идентификаторов:
- Имена ярлыков (тип
goto
).
- Теги (названия структур, союзов и перечислений).
- Члены структур и союзов (у них есть отдельное пространство имен для каждой структуры/объединения).
- Все остальные идентификаторы (имена функций, имена объектов, имена типов (def), константы перечисления и т.д.).
См. также C99 6.2.3.
Итак, на ваш два вопроса можно ответить как:
- Да, имена функций и имена typedef имеют одно и то же пространство имен.
- Не конфликтует, потому что компилятор будет использовать правила области (для имен функций или объектов). Идентификатор в основном называется теневым глобальным именем функции, что ваш компилятор предупредит вас, если вы установите уровни предупреждений достаточно высокими.
Ответ 2
Но решающим моментом в ваших примерах является не пространство имен, а область имен.
В name.c оба long2
являются "обычными идентификаторами" (совместно используют одно и то же пространство имен), и оба они определены в одной и той же области, поэтому существует конфликт. (C99, раздел 6.7/3)
Если name2.c, локальная переменная four
находится в области, более глубокой, чем функция four
, поэтому переменная скрывает функцию four
(C99 & sect; 6.2.1/4).
Ответ 3
В вашем втором примере не отображается "no conflict". Есть конфликт! Попробуйте следующее:
#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()
.