[英]Why does forward declaration of struct not work?
我用C语言编写了一个小代码,其中定义了两个结构类型,两个结构类型在其定义中具有彼此的成员。 情况1:如果在struct bar之前定义了struct foo,则代码将按预期进行编译。 情况2:如果在struct bar之后定义了struct foo,它将无法编译,这也是预期的,因为无法知道struct foo变量的内存要求。 但是我期望如果在情况2中使用struct foo的前向声明,它将编译。但是它不起作用。 我想念什么?
#include<stdio.h>
#include<stdlib.h>
struct foo; // forward declaration
struct bar
{
int a;
struct bar *next;
struct foo ch;
};
struct foo
{
struct bar *n;
struct foo *nx;
};
int main()
{
struct bar p;
return(0);
}
前向声明仅通知编译器有一个称为foo
它对大小没有任何说明。 您可以使用foo*
因为这是一个已知大小的指针,但不能使用foo
本身,因为它的大小为unknwon,因此编译器不知道bar
的内存布局应如何。
而且编译器只对您的文档进行一次遍历。 因此它不知道前面定义的结构。
如果结构类型X仅在结构声明或其函数中作为指针类型出现,并且头文件中的代码未尝试访问X的任何成员变量,则不应#include Xh,而应使其不完整在首次使用X之前先声明X(也称为“转发”声明)。以下是一个示例,其中结构类型Thing通过指针引用X:
struct X; /* incomplete ("forward") declaration */
struct Thing {
int i;
struct X* x_ptr;
};
编译器很乐意接受包含指向不完全已知的结构类型的指针的代码,这基本上是因为指针始终具有相同的大小和特征,无论它们指向什么。 通常,只有.c文件中的代码需要访问X的成员(或大小),因此.c文件将#include“ Xh”。 这是封装模块并将其与其他模块解耦的强大技术。
也就是说,如果您的代码类似于:
#include<stdio.h>
#include<stdlib.h>
struct foo; // forward declaration
struct bar
{
int a;
struct bar *next;
struct foo *ch; /* MODIFIED LINE */
};
struct foo
{
struct bar *n;
struct foo *nx;
};
int main()
{
struct bar p;
return(0);
}
但是在您的情况下,struct bar具有类型为foo的“ element”。 因此,它将给错误字段具有不完整的类型。
另外,您也可以参考以下代码段(可以正常使用):
#include<stdio.h>
#include<stdlib.h>
struct bar
{
int a;
struct aabar *next; /* MODIFIED LINE - aabar never declared */
struct foo *ch;
};
struct foo
{
struct bar *n;
struct foo *nx;
};
int main()
{
struct bar p;
return(0);
}
声明也不能让编译器知道如何分配内存。
在您的struct foo
,元素nx
是一个指针,因此定义struct foo
不需要内存大小。 但是,在struct bar
,元素ch
不是指针,因此定义struct bar
需要知道struct foo
的大小。 前向声明不指定内存大小,而是定义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.