C指向不完整的结构类型和以后的结构类型完成vs。指向未宣布的类型T_T和以后的类型T_T声明
以下是C中的法律片段:
/* Example 1. */
struct B *p; /* p: pointer to incomplete struct type B */
/* This declaration completes the struct type B. */
struct B {
int foo;
};
只要在P(例如P ++)上没有进行指针操作,直到提供了B型B的完整类型信息,片段是合法的。
另一方面,下一个片段是非法的在C:
/* Example 2. */
T_t *p; /* p: pointer to undeclared type T_t. */
typedef int T_t;
问题中:C在C中宣布指向不完整结构类型并提供完整的结构类型信息的指针是什么原因(示例1),而声明指针是非法的到未宣布的类型并稍后声明类型(示例2)?
The following is a legal fragment in C:
/* Example 1. */
struct B *p; /* p: pointer to incomplete struct type B */
/* This declaration completes the struct type B. */
struct B {
int foo;
};
As long as no pointer operations are performed on p (e.g. p++) until complete type information for struct type B is provided, the fragment is legal C.
On the other hand, the next fragment is illegal in C:
/* Example 2. */
T_t *p; /* p: pointer to undeclared type T_t. */
typedef int T_t;
Question: What is the reason that it is legal in C to declare a pointer to an incomplete struct type and provide the complete struct type information later (Example 1), whereas it is illegal to declare a pointer to an undeclared type and declare the type later (Example 2)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
由于
struct
关键字,因此已知什么样的实体struct b
是指在声明struct b
之前。它是一种类型 -struct
类型,更精确。这是一种不完整的类型,因为尚未看到struct B
的声明。但是对于某些用途,例如声明指针,这足够了。另一方面,尚不知道
t_t
是什么。是类型吗?它是变量吗?是功能吗?是枚举者吗?如果是类型,我们还可以。如果不是这样,此声明毫无意义,或更糟糕的是,取决于t_t
是什么。C语言的定义方式使编译器无需向前看。它从上到下读取,并在现场做出决定。
t_t *p;
是否可以根据已经看到的内容进行明确解释吗?如果没有,那是无效的。Because of the
struct
keyword, it is known what kind of entitystruct B
refers to, even beforestruct B
is declared. It is a type --- astruct
type, to be more precise. It is an incomplete type, because the declaration ofstruct B
has not been seen yet. But for some uses, such as declaring a pointer, it is sufficient.On the other hand it is not known what
T_t
is. Is it a type? Is it a variable? Is it a function? Is it an enumerator? If it is a type, we are OK. If it is not, this declaration either makes no sense, or worse, has more than one meaning depending on whatT_t
is.The C language is defined in such a way that the compiler does not need to look ahead much. It reads from top to bottom and decides on the spot. Can
T_t *p;
be interpreted unambiguously based on what is already seen? If not, then it is invalid.具有“标签”(结构,联合,枚举)的类型具有特殊规则(C17 6.7.2.3):
这允许 forward声明 不完整的类型,后来将完成。对于结构,此功能有一些有用的应用程序:它允许自我引用结构(例如链接列表节点),并且允许以“不透明类型”的形式进行私人封装,其中结构定义隐藏在翻译单元之外。
Types with "tags" (struct, union, enum) have special rules (c17 6.7.2.3):
This allows for forward declaration of an incomplete type which will later be completed. In case of structs there are some useful applications for this feature: it allows self-referencing structs (like linked list nodes) and it allows private encapsulation in the form of "opaque types", where the struct definition is hidden outside the translation unit.