Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested Structure Syntax

Tags:

c

I have a quick question..is there any difference in these:

struct myinnerstruct
{
    int x;

};

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

AND THIS

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

These both work as far as I can tell, but I'm wondering if there's a reason to pick one or the other. Thanks

like image 388
prelic Avatar asked Sep 07 '11 22:09

prelic


2 Answers

The difference is that the second one is invalid.

The stuff between the { and } in a struct declaration is a sequence of member declarations. Your

    struct myinnerstruct
    {
        int y;
    };

is a type declaration; it doesn't declare a member of the enclosing struct, so it's illegal in that context.

What you can do is this:

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

The declaration of m is a member declaration, so it's ok; it also declares the type struct myinnerstruct. But in my opinion, it's poor style. The type struct myinnerstruct remains visible after the declaration of struct mystruct is completed; see below for the explanation.

If you really want a struct within a struct like that, and you're not going to use struct myinnerstruct anywhere else, you could leave it without a tag:

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

But then you might as well declare y as a member of struct mystruct.

If you want struct innerstruct to be a named type, just declare it separately, as you did in your first example.

Here's the explanation of why struct innerstruct remains visible.

The C99 standard (large PDF), section 6.2.1 paragraph 2, says:

For each different entity that an identifier designates, the identifier is visible (i.e., can be used) only within a region of program text called its scope. Different entities designated by the same identifier either have different scopes, or are in different name spaces. There are four kinds of scopes: function, file, block, and function prototype. (A function prototype is a declaration of a function that declares the types of its parameters.)

The C90 and C11 standards have essentially the same wording.

The { braces } in a struct declaration do not define a block, nor do they define any of the other possible kinds of scope, so anything declared between the braces is not scoped to that region; it must be scoped to some surrounding context. It happens that the syntax lets you declare struct myinnerstruct inside another struct definition -- but only if it's part of a member definition. I think this is allowed only because the designers of the language didn't go to any extra effort to disallow it; it's just a side effect of other rules. You can do it, but I don't recommend it.

like image 62
Keith Thompson Avatar answered Oct 04 '22 03:10

Keith Thompson


A reason to choose one or the other would be conventional expectations.

A structure declaration nested within another would not be expected to be reused elsewhere, even though it can be.

Also, there is a psychological clash by not putting things of the same level of abstraction side-by-side. It is perfectly legal to do it, but it makes understanding the code a little harder and maybe more irritating.

like image 21
wallyk Avatar answered Oct 04 '22 02:10

wallyk