Почему компилятор не выдает конфликтную ошибку?

В следующем коде я объявил переменную-член структуры с тем же именем, что и имя структуры.

struct st 
{     
    int st;
};

int main()
{
   struct st t;
   t.st = 7;
   return 0;
}

Интересно, он отлично работает на компиляторе GCC и не выдает конфликтной ошибки.

So,

  • Как компилятор узнает имя структуры и имя переменной?
  • Какой механизм внутреннего использования компилятора?

person msc    schedule 10.10.2017    source источник
comment
Что возвращает main()?   -  person joop    schedule 10.10.2017
comment
Имена переменных и структур являются разными объектами для любого компилятора C, начиная с KnR. Разные пространства имен, если хотите. Так что это совершенно нормально.   -  person Matt    schedule 10.10.2017
comment
struct указывает компилятору размечать следующие st как структуру со значением st. Точно так же элемент int st объявляется как переменная int с именем st. Их использование ортогонально, поэтому компилятор не может запутаться во время лексического анализа.   -  person Mateen Ulhaq    schedule 10.10.2017
comment
Нет места, где идентификатор st мог бы быть двусмысленным. В зависимости от контекста это может быть либо имя структуры, либо имя поля, но не то и другое одновременно.   -  person axiac    schedule 10.10.2017
comment
старый способ был слишком болезненным. Так они это исправили.   -  person Hans Passant    schedule 10.10.2017


Ответы (2)


Да, это действительно. Тег структуры и элементы структуры находятся в разных пространствах имен.

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

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

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

Имя типа структуры struct st. Не только st, так что конфликта нет вообще.

person unwind    schedule 10.10.2017