为什么结构成员必须始终具有标识符?
Why must a struct member always have an identifier?
为什么结构成员必须始终有一个标识符?答案当然是因为这就是语言的定义方式,但我想了解其背后的原因。
typedef union {
int a;
struct {
int a; //Why is an identifier necessary here?
int b;
} s;
} u;
实际上,位域成员不需要名称,至少根据 gcc -std=c99 -Wall -Wextra -pedantic
,编译此代码时不会给出警告:
struct Foo
{
char x;
unsigned :8;
};
如果您真的不想为不是位域的成员使用标识符,您可以将其命名为 _reserved0
以明确表明这只是保留 space 你不想从你的代码访问。
我不知道写C标准的人的意见。也许他们认为没有名字的结构成员几乎总是一个错误(即程序员忘记了名字),他们想帮助人们捕捉这些错误,但他们对规则做了一些例外。
//Why is an identifier necessary here?
这个a
不同于结构外的a
。编译器需要知道你想访问哪一个
如果您使用不同的名称,您可以在 union
中使用匿名结构
typedef union {
int a;
struct {
int b;
int c;
};
} u;
u foo(int x, int y, int z)
{
u un;
u.a = x;
u.b = y;
u.c = z;
}
这里有语法问题。考虑 int a, b, c;
。这声明了三个对象。 int a, b;
声明两个,int a;
声明一个。那么 int;
应该申报多少?当没有声明符的声明出现在其他上下文中时,它不声明任何对象。例如,struct foo { int x; };
定义了类型 struct foo
,但它没有声明该类型的对象。
我们可以为结构中的声明做一个例外,并且说,如果他们没有声明者,那么他们声明一个未命名的成员。但是随后我们将另一种特殊情况引入到语法中。那么 struct foo { int x; };
没有声明符,当它出现在结构定义内部时,它会声明类型 struct foo
的成员对象,但当它出现在结构定义外部时,它不会声明任何对象。
所以这增加了语言的复杂性。这是没有必要的;想要结构中的成员的人总是可以给它起一个名字,并且可以选择一个不会干扰其他代码的名字。
为什么结构成员必须始终有一个标识符?答案当然是因为这就是语言的定义方式,但我想了解其背后的原因。
typedef union {
int a;
struct {
int a; //Why is an identifier necessary here?
int b;
} s;
} u;
实际上,位域成员不需要名称,至少根据 gcc -std=c99 -Wall -Wextra -pedantic
,编译此代码时不会给出警告:
struct Foo
{
char x;
unsigned :8;
};
如果您真的不想为不是位域的成员使用标识符,您可以将其命名为 _reserved0
以明确表明这只是保留 space 你不想从你的代码访问。
我不知道写C标准的人的意见。也许他们认为没有名字的结构成员几乎总是一个错误(即程序员忘记了名字),他们想帮助人们捕捉这些错误,但他们对规则做了一些例外。
//Why is an identifier necessary here?
这个a
不同于结构外的a
。编译器需要知道你想访问哪一个
如果您使用不同的名称,您可以在 union
typedef union {
int a;
struct {
int b;
int c;
};
} u;
u foo(int x, int y, int z)
{
u un;
u.a = x;
u.b = y;
u.c = z;
}
这里有语法问题。考虑 int a, b, c;
。这声明了三个对象。 int a, b;
声明两个,int a;
声明一个。那么 int;
应该申报多少?当没有声明符的声明出现在其他上下文中时,它不声明任何对象。例如,struct foo { int x; };
定义了类型 struct foo
,但它没有声明该类型的对象。
我们可以为结构中的声明做一个例外,并且说,如果他们没有声明者,那么他们声明一个未命名的成员。但是随后我们将另一种特殊情况引入到语法中。那么 struct foo { int x; };
没有声明符,当它出现在结构定义内部时,它会声明类型 struct foo
的成员对象,但当它出现在结构定义外部时,它不会声明任何对象。
所以这增加了语言的复杂性。这是没有必要的;想要结构中的成员的人总是可以给它起一个名字,并且可以选择一个不会干扰其他代码的名字。