为什么内部结构中不允许使用typedef?

我有一个程序,在现有的typedef结构中定义一个typedef结构,我想知道为什么我得到一个编译错误。

这是程序:

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; } 

在编译时给出以下错误::

 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' 

但是,当我把程序改为

 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; } 

它编译成功。

为什么内部结构不允许使用typedef?

C在结构成员的声明中不允许存储类说明符( typedef ,但也包括staticextern )。 这在C99中6.7.2.1p1中的结构和联合声明的语法中指定。

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

您可以将6.7.2.1p1语法与声明的语法进行比较,其中声明符不是函数参数或6.7p1中的结构/联合成员,并且在这种情况下可以看到存储类说明符是允许的。

struct定义中包含typedef是相当奇怪的风格。

通常, struct定义的{}之间应该出现的唯一事物是struct成员的声明。

正如ouah所说, struct定义中的声明不能包含存储类说明符; 存储类说明符是typedefexternstaticautoregister (和C11添加_Thread_local )。 这种限制是有道理的,因为结构成员的存储完全取决于它所属的结构的存储。

typedef是一个特例; 它没有指定存储类,但为了方便,它被视为存储类说明符

可以在结构定义中包含其他类型的声明; 例如,正如您所见,您可以将结构声明嵌套在另一个中。 例如,这个程序是有效的(据我所知):

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

但是gcc警告说嵌套声明:

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

(在我尝试之前,我认为这是非法的。)

更新gcc -pedantic-errors拒绝此致命错误,表明这是非法的。 我会尝试用标准validation这是非法的。

我认为最好的做法是在结构中只有成员声明。 如果需要声明另一个类型,请在struct声明之外声明它。 例如,我在这样的问题中重写代码:

 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; } 

(实际上,我会这样写:

 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; }