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

问题描述

在学习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,&mydata};
    std::cout << (*mydata.c).a;
    return 0;
}

解决方法

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

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

8在目录中存在结构声明列表 struct-or-union-specifier在翻译中声明一个新类型 单元。 struct-declaration-list是一系列声明的 结构或工会的成员。如果struct-declaration-list 没有命名成员,没有匿名结构,也没有匿名 工会,行为是不确定的。 类型不完整,直到 立即终止列表的}之后,并完成 之后。

或者来自C ++ 14 Standard(9.2类成员)

2 类被视为完全定义的对象类型(3.9)(或 完整类型)在类说明符的结尾} 。内 类成员规范,该类被认为是完整的 函数体,默认参数,使用声明介绍 继承构造函数(12.9),异常规范和 非静态数据成员的brace-or-equal-initializer s(包括 嵌套类中的此类内容)。否则被认为是不完整的 在自己的类成员规范中。

所以在这个声明中

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

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

根据C标准(6.2.5类型)

  1. ...在翻译单元内的各个点上,对象类型可能是 不完整(缺少足够的信息来确定 该类型的对象)或完整的(具有足够的信息)。

另一方面,指针始终是完整类型。它们的大小总是众所周知的。

根据C标准(6.2.5类型)

-指针类型可以从函数类型或对象派生 类型,称为引用类型。指针类型描述对象 其值提供对引用类型的实体的引用。 从引用类型T派生的指针类型有时称为 ‘T的指针’。从引用中构造指针类型 类型称为“指针类型派生”。 指针类型是 完整的对象类型

请注意您的程序不是C程序,因为C没有标题<iostream>。您展示了C ++程序。

尽管如此,我提供的引号对C ++也有效。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...