Почему имена typedef могут использоваться в качестве имен членов структуры? - PullRequest
7 голосов
/ 29 апреля 2020

Я только что обнаружил, что и gcc, и clang принимают следующий код:

typedef int blah;
struct s { char blah; };

Однако они отклоняют это, поскольку имя типа используется в качестве идентификатора:

typedef int blah;
char blah;

Означает ли это, что имя typedef не видно внутри определения структуры? Нет, потому что это работает как в g cc, так и в clang:

typedef int blah;
struct s { blah blah; }

Я смотрю в стандарте C99 и не могу найти ничего, что объясняет, почему имя typedef может использоваться в качестве имени члена структуры, но не переменной в той же области.

Может кто-нибудь объяснить, почему это так? Ссылка на любой применимый стандарт приветствуется.

Ответы [ 2 ]

9 голосов
/ 29 апреля 2020

Члены структур и обычных переменных находятся в разных пространствах имен. Вот почему две обычные переменные с одинаковым именем идентификатора терпят неудачу, тогда как если в элементе структуры используется одно и то же имя идентификатора, а обычная переменная подходит.

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

6.2.3 Пространства имен идентификаторов

Если в какой-либо точке единицы перевода видно более одного объявления конкретного идентификатора, контекст syntacti c устраняет неоднозначность использования которые относятся к разным субъектам. Таким образом, существуют отдельные пространства имен для различных категорий идентификаторов, а именно:

  • имена меток (устранены неоднозначно по синтаксису объявления и использования меток);
  • метки структур , союзы и перечисления (устраняющие неоднозначность, следуя любому 32) ключевых слов struct, union или enum);
  • членов структур или объединений; каждая структура или объединение имеет отдельное пространство имен для своих членов (неоднозначное по типу выражения, используемого для доступа к члену через оператор. или ->);
  • все другие идентификаторы, называемые обычными идентификаторами (объявленными в обычные деклараторы или константы перечисления).

(последние два пункта маркера напрямую касаются этого вопроса)

Да, идентификаторы typedef 'ed совместно используют пространство имен с обычные идентификаторы. 6.7.8 Определения типов :

[...] Имя typedef имеет то же пространство имен, что и другие идентификаторы, объявленные в обычных объявлениях.

2 голосов
/ 29 апреля 2020

Взято отсюда: https://www.spinellis.gr/cscout/doc/name.html

C имеет 4 различных пространства имен. Это не пространства имен из C ++, доступ к которым осуществляется с помощью ключевого слова namespace. Скорее, это отдельные области для символов:

  • Теги для struct / union / enum

  • Члены struct / union (фактически отдельные пространство имен присваивается каждой структуре / объединению)

  • Метки

  • Обычные идентификаторы (называются объектами в стандарте C)

...