Why is typedef not allowed in the internal structure?

I have a program that defines a typedef structure in an existing typedef structure, and I wonder why I get 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; } 

at compilation gives the 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 internal structures?

+4
source share
2 answers

C does not allow a storage class specifier ( typedef , or static or extern ) in a member declaration. This is indicated in the syntax for declaring structures and unions in 6.7.2.1p1 in C99.

 /* The compiler will issue a diagnostic for this declaration */ struct s { static int a; }; 

You can compare the syntax of 6.7.2.1p1 with the syntax of a declaration in which declarator is not a function parameter or a member of a structure / union in 6.7p1 and does not see that storage class specifiers are valid in this case.

+11
source

It is a rather strange style to have a typedef inside a struct definition.

Typically, the only things that should appear between the { and } a struct definition are declarations of members of the structure.

As ouah says, an declaration in a struct definition cannot contain a storage class specifier; storage class specifiers typedef , extern , static , auto and register (and C11 adds _Thread_local ). This limitation makes sense, since the storage for the structure element is completely determined by the storage of the structure of which it is a member.

And typedef is a special case; it does not specify a storage class, but it is considered as a storage class specifier for syntax convenience.

You may have other types of declarations within the structure definition; for example, as you saw, you can nest a structure declaration inside another. For example, this program is valid (as far as I can tell):

 struct outer { struct inner { int x; }; // line 4 struct inner foo; }; int main(void) { struct outer obj; obj.foo.x = 42; return 0; } 

But gcc warns of a nested declaration:

 cc:4:6: warning: declaration does not declare anything [enabled by default] 

(And before I tried this, I would suggest that it is illegal.)

UPDATE : gcc -pedantic-errors rejects this with a fatal error, which indicates its illegality. I will try to check with the standard that it is illegal.

I think the best practice is to have only member declarations within the structure. If you need to declare a different type, declare it outside the structure declaration. For example, I would rewrite the code in the question as follows:

 typedef struct Inner { int b; } INNER; typedef struct Outer { INNER inner; int a; } OUTER; int main(void) { OUTER obj; obj.a = 10; obj.inner.b=8; return 0; } 

(Actually, I would write it like this:

 struct inner { int b; }; struct outer { struct inner inner; int a; }; int main(void) { struct outer obj; obj.a = 10; obj.inner.b = 8; return 0; } 
+5
source

All Articles