它们是两种匿名的结构体类型(它们都没有标签)。所有这样的结构体类型(在单个翻译单元中)都是不同的-它们从未是相同的类型。请添加一个标签!
标准中相关的句子在§6.7.2.1 结构体和联合体规范中:
¶8在结构或联合体规范中存在struct-declaration-list会声明一个新类型,在翻译单元内。
struct-declaration-list指的是类型中{
和}
之间的部分。
这意味着在您的代码中,有两种不同的类型,每个struct { … }
对应一种类型。这两种类型是不同的。您不能将一个类型的值正式分配给另一个类型,也不能创建指针等。实际上,在分号后,您无法再次引用这些类型。
这意味着你可以有:
int main(void)
{
struct {int x; int y;} test = {42, 1337}, *tp = &test;
struct {int x; int y;} result, *result_ptr;
result_ptr = &result;
…
}
现在,test
和tp
指向相同的类型(一个是结构体,一个是指向结构体的指针),result
和result_ptr
也是如此,初始化和赋值都很好,但这两种类型是不同的。不清楚是否创建了任何一种复合文字类型 —— 你必须写(struct {int x; int y;}){.y = 9, .x = 8}
,但存在struct-declaration-list的存在意味着这是另一种新类型。
正如评论中所述,还有第§6.2.7节的Compatible type and composite type,其中写道:
¶1...此外,如果它们的标记和成员满足以下要求,则在单独的翻译单元中声明的两种结构、联合或枚举类型是兼容的:如果其中一个使用标记进行声明,则另一个应使用相同的标记进行声明。如果两个在各自的翻译单元中的任何地方都已完成,则应满足以下附加要求:它们之间应该有一对一的对应关系,使得每一对相应的成员都声明为兼容类型;如果一对中的一个成员声明了对齐说明符,则另一个成员声明了与之等效的对齐说明符;如果一对中的一个成员声明了名称,则另一个成员声明了相同的名称。对于两个结构体,相应的成员应按照相同的顺序声明。对于两个结构体或联合,相应的位字段应具有相同的宽度。
粗略地说,如果两个翻译单元(类似于“源文件”加上包含的头文件)中类型定义相同,则它们指向相同的类型。感谢上帝!否则,你不能使用标准 I/O 库,还有其他细节问题。
void*
:struct {int x; int y;} *test_ptr = (void*)&test;
- achvoid*
和例如int*
是不兼容的,但是它们可以被赋予彼此(存在隐式转换)。 - Keith Thompson