区别在于第二个是无效的。
结构声明中{
和}
之间的内容是一系列成员声明。您的
struct myinnerstruct
{
int y;
};
是一种类型声明;它没有声明封闭结构的成员,所以在这种情况下它是非法的。
什么你可以做的是:
struct mystruct
{
int x;
struct myinnerstruct
{
int y;
} m;
};
的m
的声明是一个成员声明,所以它的确定;它还声明了类型struct myinnerstruct
。但在我看来,这是不好的风格。在struct mystruct
的声明完成后,struct myinnerstruct
类型仍然可见;请参阅下面的解释。
如果你真的想这样的一个结构内的结构,而你不打算使用struct myinnerstruct
其他地方,你可以离开它没有一个标签:
struct mystruct
{
int x;
struct
{
int y;
} m;
};
但你还不如申报y
作为struct mystruct
的成员。
如果你想让struct innerstruct
成为一个命名类型,只需单独声明它,就像你在第一个例子中一样。
下面是对的解释,为什么struct innerstruct
仍然可见。
的C99 standard(大PDF),第6.2.1节第2段表示:
对于标识符指定每个不同实体,所述 标识符只(即,可以使用)是可见在 区域内的程序文本称为其范围。由 指定的不同实体相同的标识符或者具有不同的范围,或者以不同的名称 空格。函数原型有四种类型的函数:函数,文件,块和 。 (A 函数原型是 函数声明的类型的其参数的声明。)
的C90和C11的标准具有基本上相同的措辞。
{
大括号}
在结构声明中没有定义块,也没有定义任何其他可能的范围,因此大括号之间声明的任何内容都不在该范围内;它必须限定在某些周围的环境中。碰巧语法允许你在另一个结构定义中声明struct myinnerstruct
- 但只有它是成员定义的一部分。我认为这只是因为该语言的设计者没有任何额外的努力来阻止它;这只是其他规则的副作用。你可以做到这一点,但我不推荐它。
第二个变体是否合法C? –
我还没有真正能够在网上找到它的任何例子。我的测试都返回相同的结果。所以AFAIK,它是。 – prelic
下面的内容也会起作用,使第二个缩短一点:struct mystruct {int x; struct myinnerstruct {int y; } m; };恕我直言,在另一个'struct'内定义一个'struct'的最好理由是当内部''struct'被独占使用并且可能重复地作为外部'struct'的成员时,也就是说'struct'必须有许多“团体”为不同的目的存储类似的信息。 –