Не то чтобы я когда-либо писал в своей профессиональной работе такой код, как следующий, следующий код является допустимым и компилируется без предупреждений в C ++ и c:
#include <stdlib.h>
typedef struct foo { int foo; } foo;
foo * alloc_foo () {
return (struct foo*) malloc(sizeof(foo));
}
struct foo * alloc_struct_foo () {
return (foo*) malloc(sizeof(struct foo));
}
foo * make_foo1 (int val) {
foo * foo = alloc_struct_foo ();
foo->foo = 0;
return foo;
}
struct foo * make_foo2 (int val) {
struct foo * foo = alloc_foo();
foo->foo = 0;
return foo;
}
Что делает это законный и недвусмысленный в C раздел 6.2.3 стандарта C:
6.2.3 Пространства имен идентификаторов
Если в любой точке единицы перевода, синтаксический контекст устраняет неоднозначность использования, относящегося к разным объектам. Таким образом, существуют отдельные пространства имен для различных категорий идентификаторов (имена меток; теги структур, объединений и перечислений; члены структур или объединений; и обычные идентификаторы).
Обратите внимание, что благодаря именам меток, живущим в своих собственных пространствах имен, я мог бы сделать код еще более запутанным, используя где-нибудь метку foo
.
Добавьте следующее, и код не компилируется:
int foo (foo * ptr) {
return ++ptr->foo;
}
Итак, два вопроса: один относится к C и C ++, а другой - к C ++.
Вопрос C / C ++: Почему я не могу определить функцию foo
?
Кажется, я смогу определить функцию foo
; Имена функций и имена переменных являются «обычными идентификаторами». Но если я добавлю этот последний фрагмент кода, я получу ошибку : переопределение 'foo' как другого символа
.
Вопрос: foo * foo;
совершенно законен, так почему же int foo (foo *);
не разрешен?
Вопрос C ++: Как это вообще работает в C ++?
Значение слова «пространство имен» в C ++ приобретает совершенно иное значение, чем в C. Я не могу найти ничего в стандарте C ++, где говорится о концепция пространств имен C, которая делает вышеуказанное законным в C.
Вопрос: Что делает это законным в C ++ (предпочтительнее глава и стих)?