Объем структуры, объявленной/определенной в рамках другой структуры

Чтение из Вложенных структур, я понял, что структура, объявленная в другой структуре, имеет ту же область, что и содержащая структура. Я думал, что он ограничен только внутри содержащейся структуры. У меня сложилось впечатление, что ссылка . В нем указано, что существует 4 пространства имен, и один из них является членом структуры. Я "логически" предполагал, что внутренние структуры ограничены только внешним.

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

Вопрос 2. Для терминологии, когда я предоставляю члены структуры, скажите

struct out{
    int a, b;
    char c, d;
    struct in{
        int a, b;
    }e;
};

Я предоставляю определение как для struct out, так и struct in; ИЛИ я предоставляю декларацию для обоих? Я понимаю разницу для функций и примитивных типов данных, но здесь не совсем понятно для struct.

EDIT: Полезная ссылка Я только что нашел в SO: Вложенные структуры в C и С++.

Но там это не дает никакого объяснения. И теперь я сомневаюсь, что есть один для C...

Ответ 1

Для стандарта проекта C99 правила для области охвата указаны в 6.2.1 Области идентификаторов, а в пункте 7 говорится (основное внимание)

Теги Structure, union и enumeration имеют область видимости, которая начинается сразу после появления тега в спецификаторе типа, который объявляет тег. Каждая константа перечисления имеет область действия, которая начинается сразу после появления его определяющего перечислителя в списке перечислителей. Любой другой идентификатор имеет область действия, которая начинается сразу после завершения его декларатора.

Область заканчивается в соответствии с правилами, изложенными в пункте 4:

Каждый другой идентификатор имеет область, определяемую размещением его декларации (в декларатор или спецификатор типа). Если спецификатор декларатора или типа, объявляющий идентификатор, появляется за пределами любого блока или списка параметров, идентификатор имеет область действия файла, которая заканчивается в конце единицы перевода. Если декларатор или спецификатор типа, объявляющий идентификатор, появляется внутри блока или в списке объявлений параметров в определении функции, идентификатор имеет область блока, которая заканчивается в конце связанного блока. [...]

Что касается логики, то это, вероятно, связано с тем, что в отличие от С++, в C у нас нет оператора разрешения области (::).

Что касается вопроса 2, вы предоставляете определение и объявление в своем примере, это будет пример просто объявления:

struct out ;

Также см.: В чем разница между определением и декларацией?.

Для списка всех несовместимостей между C и С++ вы можете проверить Несовместимость между ISO C и ISO С++ он охватывает эту тему здесь.

Ответ 2

В C нет каких-либо "скрывающих деталей реализации", которые, по-вашему, определяют структурный тег, текстовые внутри внешней структуры, являются случайными. (Нет пространств имен, нет ::)

В С++ инкапсуляция (скрытие) очень актуальна, она рассматривает внутреннюю структуру, определяющую тип, внутренний для out (в своем пространстве имен), который нельзя использовать за пределами, если специально не вызвано с помощью ::. Классы и структуры в С++ - это почти одно и то же, поэтому здесь struct, а не class.

Один из интересных способов, в которых отличаются C и С++.