C指向不完整的结构类型和以后的结构类型完成vs。指向未宣布的类型T_T和以后的类型T_T声明

发布于 2025-02-13 13:13:52 字数 487 浏览 1 评论 0原文

以下是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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ヤ经典坏疍 2025-02-20 13:13:52

由于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 entity struct B refers to, even before struct B is declared. It is a type --- a struct type, to be more precise. It is an incomplete type, because the declaration of struct 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 what T_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.

情深缘浅 2025-02-20 13:13:52

具有“标签”(结构,联合,枚举)的类型具有特殊规则(C17 6.7.2.3):

所有具有相同范围的结构,工会或枚举类型的声明
使用相同的标签声明相同的类型。无论是标签还是什么
该类型的其他声明在同一翻译单元中,该类型不完整,直到列表结束后立即定义内容,然后完成。

这允许 forward声明 不完整的类型,后来将完成。对于结构,此功能有一些有用的应用程序:它允许自我引用结构(例如链接列表节点),并且允许以“不透明类型”的形式进行私人封装,其中结构定义隐藏在翻译单元之外。

Types with "tags" (struct, union, enum) have special rules (c17 6.7.2.3):

All declarations of structure, union, or enumerated types that have the same scope and
use the same tag declare the same type. Irrespective of whether there is a tag or what
other declarations of the type are in the same translation unit, the type is incomplete until immediately after the closing brace of the list defining the content, and complete thereafter.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文