В C (6.2.3 Пространства имен идентификаторов) понятие пространств имен определяется следующим образом.
1 Если в любой точке единицы перевода видно более одного объявления конкретного идентификатора, синтаксический контекст устраняет неоднозначность использования, относящегося к разным объектам. Таким образом, существуют отдельные пространства имен для различных категорий идентификаторов, а именно:
- имена меток (устраненные синтаксисом объявления и использования метки);
- теги структур, объединений и перечислений (устраняются неоднозначностью, следуя any32) ключевых слов struct, union или enum);
— члены структур или союзов; каждая структура или объединение имеет отдельное пространство имен для своих членов (неоднозначность определяется типом выражения, используемого для доступа к члену с помощью оператора . или ->);
— все остальные идентификаторы, называемые обычными идентификаторами (объявленные в обычных деклараторах или как константы перечисления).
Так, например, имя тега структуры может совпадать с именем функции, потому что они принадлежат разным пространствам имен. Когда вы указываете структуру с именем тега структуры, когда вы должны использовать ключевое слово struct
. Так, например, эти объявления не конфликтуют.
struct s
{
int s;
};
void s( void );
struct s s1;
В этом фрагменте кода имя тега s
структуры не конфликтует с именем функции s
, поскольку имя тега должно быть указано с ключевым словом struct
.
В C++ разрешено использовать имена структурных тегов без ключевого слова struct
.
Например
struct s
{
int s;
};
s s;
является правильным кодом. В этой декларации
s s;
имя объявленного идентификатора s
скрывает имя структуры. ТАК если то напишешь к примеру
s s1;
то компилятор выдаст ошибку, потому что в этом операторе s рассматривается как имя объявленного выше идентификатора. Чтобы устранить двусмысленность, вам нужно использовать ключевое слово struct
struct s
{
int s;
};
s s;
struct s s1;
Это описано в следующей цитате из стандарта C++ 20 (6.3.1 Декларативные области и области).
4 Учитывая набор объявлений в одной декларативной области, каждое из которых определяет одно и то же неполное имя,
(4.1) — все они должны относиться к одному и тому же объекту или все относятся к функциям и шаблонам функций; или же
(4.2) — ровно одно объявление должно объявлять имя класса или имя перечисления, которое не является именем typedef, а все остальные объявления должны ссылаться на одну и ту же переменную, нестатический член данных или перечислитель, или все ссылаться на функции и шаблоны функций. ; в этом случае имя класса или имя перечисления скрыто (6.3.10). [ Примечание. Имя пространства имен или имя шаблона класса должно быть уникальным в своей декларативной области (10.3.2, пункт 17). — конец примечания ]
Как видно из цитаты, имя пространства имен должно быть уникальным в своей декларативной области. Итак, эти декларации
struct Foo { };
namespace Foo { }
неверны.
person
Vlad from Moscow
schedule
17.03.2020
[stmt.label]/1
и одно для макросов < a href="https://eel.is/c++draft/cpp#replace-8" rel="nofollow noreferrer">[cpp]/8
. - person YSC   schedule 17.03.2020[class.name]/2
. - person YSC   schedule 17.03.2020