为什么包含结构指针成员的结构编译但包含简单结构成员的结构不编译

Why a structure containing a struct pointer member compile but containing a simple struct member does not compile

在学习 c 语言的结构时,我很困惑为什么以下代码无法编译。

#include <iostream>
struct data{
    int a;
    int b;
    struct data c;
};

typedef struct data data_t;

int main()
{
    data_t mydata = {1,2,{3,4}};
    std::cout << mydata.a;

    return 0;
}

但是这段代码编译没有任何错误。

#include <iostream>
struct data{
    int a;
    int b;
    struct data *c;
};

typedef struct data data_t;

int main()
{
    data_t mydata = {1,2,&mydata};
    std::cout << (*mydata.c).a;
    return 0;
}

结构是右大括号后的完整类型。

来自 C 标准(6.7.2.1 结构和联合说明符)

8 The presence of a struct-declaration-list in a struct-or-union-specifier declares a new type, within a translation unit. The struct-declaration-list is a sequence of declarations for the members of the structure or union. If the struct-declaration-list contains no named members, no anonymous structures, and no anonymous unions, the behavior is undefined. The type is incomplete until immediately after the } that terminates the list, and complete thereafter.

或来自 C++ 14 标准(9.2 Class 成员)

2 A class is considered a completely-defined object type (3.9) (or complete type) at the closing } of the class specifier. Within the class member-specification, the class is regarded as complete within function bodies, default arguments, using-declarations introducing inheriting constructors (12.9), exception-specifications, and brace-or-equal-initializer s for non-static data members (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.

所以在这个声明中

struct data{
    int a;
    int b;
    struct data c;
};

声明数据成员 c 的结构还不是完整类型。所以编译器不知道数据成员c的大小是多少。所以编译器无法生成结构的定义。

来自 C 标准(6.2.5 类型)

  1. ... At various points within a translation unit an object type may be incomplete (lacking sufficient information to determine the size of objects of that type) or complete (having sufficient information).

另一方面,指针总是完整的类型。它们的大小总是已知的。

来自 C 标准(6.2.5 类型)

— A pointer type may be derived from a function type or an object type, called the referenced type. A pointer type describes an object whose value provides a reference to an entity of the referenced type. A pointer type derived from the referenced type T is sometimes called ‘‘pointer to T’’. The construction of a pointer type from a referenced type is called ‘‘pointer type derivation’’. A pointer type is a complete object type.

注意你的程序不是C程序,因为C没有头文件<iostream>。你展示了 C++ 程序。

尽管如此,我提供的引用也适用于 C++。