I have a program that defines a typedef struct within an existing typedef struct, and I am wondering why I am getting a compilation error.
Here is the program:
typedef struct Outer
{
typedef struct Inner
{
int b;
}INNER;
INNER inner;
int a;
}OUTER;
int main()
{
OUTER obj;
obj.a = 10;
obj.inner.b=8;
return 0;
}
on compilation gives following error ::
test.c:3:5: error:expected specifier-qualifier-list before ‘typedef’
test.c: In function ‘main’:
test.c:17:5: error: ‘OUTER’ has no member named ‘a’
test.c:18:5: error: ‘OUTER’ has no member named ‘inner’
but, when I changed the program to
typedef struct Outer
{
struct Inner
{
int b;
};
struct Inner inner;
int a;
}OUTER;
int main()
{
OUTER obj;
obj.a = 10;
obj.inner.b=8;
return 0;
}
it compiles successfully.
Why is typedef not allowed with inner structures?
C does not allow a storage-class specifier (
typedef
, but alsostatic
orextern
) in the declaration of a structure member. This is specified in the syntax of structures and unions declaration in 6.7.2.1p1 in C99.You can compare 6.7.2.1p1 syntax with the syntax of a declaration where the declarator is not a function parameter or a structure / union member in 6.7p1 and see that in this case the storage-class specifiers are allowed.
It's rather odd style to have a typedef inside a
struct
definition.Normally the only things that should appear between the
{
and}
of astruct
definition are declarations of members of the structure.As ouah says, a declaration within a
struct
definition cannot include a storage class specifier; the storage class specifiers aretypedef
,extern
,static
,auto
, andregister
(and C11 adds_Thread_local
). This restriction makes sense because the storage for a struct member is determined entirely by the storage of the structure of which it's a member.And
typedef
is a special case; it doesn't specify a storage class, but it's treated as a storage class specifier for syntactic convenience.You can have other kinds of declarations inside a struct definition; for example, as you've seen, you can nest a struct declaration inside another. For example, this program is valid (as far as I can tell):
But gcc warns about the nested declaration:
(And before I tried this, I would have assumed it was illegal.)
UPDATE :
gcc -pedantic-errors
rejects this with a fatal error, suggesting it's illegal. I'll try to verify with the standard that this is illegal.I think the best practice is to have only member declarations inside a struct. If you need to declare another type, declare it outside the struct declaration. For example, I'd rewrite the code in the question like this:
(Actually, I'd write it like this: