Ответ 1
Разница между C и С++ заключается в следующем. В C член данных i
рассматривается как имеющий тип int
, потому что если вы хотите, чтобы у него был тип struct i
, тогда вам нужно написать struct i i
с указанием ключевого слова struct
до i
.
Структурные теги находятся в собственном пространстве имен по сравнению с пространством имен других переменных.
В соответствии со стандартом C (6.2.3. Идентификационные пространства идентификаторов)
1 Если отображается более одного объявления определенного идентификатора в любой точке единицы перевода, синтаксический контекст disambigutates использует, которые относятся к различным сущностям. Таким образом, существуют отдельные пространства имен для различных категорий идентификаторов, как следующим образом:
- имена меток (неоднозначно синтаксис объявления метки и использование);
- теги структур, объединений и перечислений (неоднозначно после any32) ключевых слов struct, union или enum);
- члены структур или союзов; каждая структура или объединение имеет отдельное пространство имен для своих членов (неоднозначно по типу выражение, используемое для доступа к элементу через. или → );
- все другие идентификаторы, называемые обычными идентификаторами (объявленными в обычные деклараторы или константы перечисления).
Что касается С++, то внутри определения структуры имя структуры скрывает имя typedef, а компилятор выдает ошибку. В С++ существует отдельная область класса.
Например, в С++ (поиск по имени 3.4) записано
3 Введенное имя класса класса (раздел 9) также рассматривается быть членом этого класса для целей скрытия имени и поиск.
и (3.4.1 Поиск неквалифицированного имени)
7 Имя, используемое в определении класса X вне члена тело функции или определение вложенного класса29 должно быть объявлено в одном из следующие способы: - перед его использованием в классе X или быть членом базовый класс X (10.2) или...
Таким образом, введенное имя класса скрывает имя typedef в определении класса.
Учесть, что вне определения класса имя класса можно скрыть одним и тем же именем объекта. Таким образом, если вы хотите объявить объект класса в этой области, вы должны использовать его выработанное имя, например
int i;
struct i {};
//...
struct i obj;