Синтаксис вложенной структуры - PullRequest
5 голосов
/ 08 сентября 2011

У меня быстрый вопрос ... есть ли разница в этих:

struct myinnerstruct
{
    int x;

};

struct mystruct
{
    struct myinnerstruct m;
    int y;
};

И ЭТОГО

struct mystruct
{
    int x;
    struct myinnerstruct
    {
        int y;
    };
    struct myinnerstruct m; 
};

Они оба работают, насколько я могу судить, но мне интересно, есть ли причина выбрать один или другой. Спасибо

Ответы [ 2 ]

7 голосов
/ 08 сентября 2011

Разница в том, что второй недействителен.

Материал между { и } в объявлении структуры представляет собой последовательность объявлений членов. Ваш

    struct myinnerstruct
    {
        int y;
    };

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

Что вы можете сделать это:

struct mystruct
{
    int x;
    struct myinnerstruct
    {
        int y;
    } m;
};

Объявление m является объявлением члена, так что все в порядке; он также объявляет тип struct myinnerstruct. Но, на мой взгляд, это плохой стиль. Тип struct myinnerstruct остается видимым после завершения объявления struct mystruct; объяснение см. ниже.

Если вам действительно нужна структура внутри такой структуры, и вы не собираетесь использовать struct myinnerstruct где-либо еще, вы можете оставить ее без тега:

struct mystruct
{
    int x;
    struct
    {
        int y;
    } m;
};

Но тогда вы можете также объявить y как член struct mystruct.

Если вы хотите, чтобы struct innerstruct был именованным типом, просто объявите его отдельно, как вы это делали в первом примере.

Вот объяснение , почему struct innerstruct остается видимым.

Стандарт C99 (большой PDF), раздел 6.2.1, параграф 2, гласит:

Для каждого отдельного объекта, который обозначает идентификатор, идентификатор видимый (то есть может использоваться) только в пределах области текст программы называется scope . Различные лица, обозначенные один и тот же идентификатор имеет разные области действия или имеет другое имя пространства. Существует четыре вида областей действия: функция, файл, блок и прототип функции. (A прототип функции является объявлением функция, которая объявляет типы своих параметров.)

Стандарты C90 и C11 имеют практически одинаковую формулировку.

{ фигурные скобки } в объявлении структуры не определяют блок и не определяют другие возможные области видимости, поэтому все, что объявлено между фигурными скобками, не попадает в эту область; это должно быть ограничено некоторым окружающим контекстом. Бывает, что синтаксис позволяет вам объявить struct myinnerstruct внутри другого определения структуры - но только если это часть определения члена. Я думаю, что это разрешено только потому, что разработчики языка не приложили никаких дополнительных усилий, чтобы запретить его; это просто побочный эффект других правил. Вы можете сделать это, но я не рекомендую.

1 голос
/ 08 сентября 2011

Причиной выбора того или другого были бы обычные ожидания.

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

Кроме того, существует психологическое столкновение, когда предметы одного уровня абстракции не соседствуют друг с другом. Это совершенно законно, но это делает понимание кода немного сложнее и, возможно, более раздражающим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...