为什么在没有我的结构的前向声明的情况下进行编译?
struct Figlio
{
char nome[256];
struct Genitore* padre;
struct Genitore* madre;
};
struct Genitore
{
char nome[256];
struct Figlio* progenie;
};
int main()
{
return 0;
}
我预计上面的代码不会编译,因为 struct Genitore
没有在 Figlio
之前声明,因此 Genitore
的前向声明(即 >struct Genitore;
在顶部)是需要的。相反,在 C 中,它编译没有任何问题。
相反,如果我将尚未声明的结构指针传递给函数,例如,
void f(struct st*);
struct st{};
它会引发以下警告
警告:参数列表内声明的“struct st”在此定义或声明之外不可见
因此,我不明白为什么会有这些不同的行为,特别是为什么要向前声明 struct Genitore; 和分别不要求struct st;
。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个范围问题。
首先,对于有关
struct
标记的规则,请参阅 C 标准 规定:这使得
struct
标记无论出现在哪里都可以充当声明。这还允许结构包含指向自身的指针并使其引用相同的类型。那么标识符范围的规则在第6.2.1p4节中列出:
特别注意两个粗体段落。将指向该类型的指针声明为 struct Figlio 的成员时,struct Genitore 的隐式声明具有文件作用域,因为它不会出现在块语句中,也不会出现在函数声明中,因此从源文件中的该点向下可见。
相反,出现在函数声明中的隐式声明仅在声明本身的范围内。这样的类型声明是有问题的,因为您传入的任何潜在结构指针都将引用与函数声明中隐式声明的类型不同的类型。
This is a matter of scope.
First, for the rule regarding a
struct
tag, section 6.2.1p7 of the C standard states:Which is what allows the appearance of a
struct
tag to act as a declaration wherever it appears. This also allows a struct to contain a pointer to itself and have it refer to the same type.Then the rules for the scope of identifiers is listed in section 6.2.1p4:
Note in particular the two bolded passages. The implicit declaration of
struct Genitore
when declaring a pointer to that type as a member ofstruct Figlio
has file scope, since it does not appear in a block statement and does not appear in a function declaration, and therefore is visible from that point down in the source file.In contrast, the implicit declaration that appears in the function declaration is only in scope for the declaration itself. Such a type declaration is problematic because any potential struct pointer that you pass in will refer to a different type than the one implicitly declared in the function declaration.
在此声明中,
您声明了两个指向不完整类型 struct Genitore 的指针。
指针类型是一个完整的对象类型。
也就是说,在这些声明中,您声明了不完整类型 struct Genitore 和指针类型 struct Genitore * 的对象。
结构体类型 struct Genitore 的声明在声明结构体 Figlio 的作用域中可见(在文件作用域或块作用域中)
引入不完整结构体的另一个例子type 是 typedef 声明中的一个声明,例如
typedef struct AA;
。您可以在同一范围内的 typedef 声明之后的某个位置定义该结构。
另一个示例是在函数声明的返回类型中声明结构不完整类型。例如
,您至少需要在函数定义之前或函数调用之前定义结构。
这是一个演示程序。
程序输出是
另一方面,如果您尝试取消引用指向不完整类型的指针,编译器将发出错误。
在此声明中,
类型说明符 struct st 具有函数原型范围,并且在函数参数列表之外不可见。
来自 C 标准(6.2.1 标识符的范围)
In this declaration
you declared two pointers to the incomplete type
struct Genitore
.A pointer type is a complete object type.
That is in these declarations you declared the incomplete type
struct Genitore
and objects of the pointer typestruct Genitore *
.The declaration of the structure type
struct Genitore
is visible in the scope where the structureFiglio
is declared (in a file scope or a block scope)Another example of introducing an incomplete structure type is a declaration it in a typedef declaration for example
typedef struct A A;
.You can define the structure somewhere below after the typedef declaration in the same scope.
Another example is declaring a structure incomplete type in the return type of a function declaration. For example
Again you will need to define the structure at least before the function definition or before a function call.
Here is a demonstration program.
The program output is
On the other hand, if you will try to dereference a pointer to an incomplete type the compiler will issue an error.
In this declaration
the type specifier
struct st
has the function prototype scope and is not visible outside the function parameter list.From the C Standard (6.2.1 Scopes of identifiers)