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
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With