简体   繁体   English

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

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

While learning about structures in c language I am confused that why the following code 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;
}

But this code compiles without any error.但是这段代码编译没有任何错误。

#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;
}

A structure is a complete type after the closing brace.结构是右括号后的完整类型。

From the C Standard (6.7.2.1 Structure and union specifiers)来自 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. 8 struct-or-union-specifier 中struct-declaration-list 的存在声明了一个翻译单元内的新类型。 The struct-declaration-list is a sequence of declarations for the members of the structure or union. struct-declaration-list 是结构或联合成员的声明序列。 If the struct-declaration-list contains no named members, no anonymous structures, and no anonymous unions, the behavior is undefined.如果 struct-declaration-list 不包含命名成员、匿名结构和匿名联合,则行为未定义。 The type is incomplete until immediately after the } that terminates the list, and complete thereafter.在终止列表的 } 之后,类型是不完整的,然后是完整的。

Or from the C++ 14 Standard (9.2 Class members)或来自 C++ 14 标准(9.2 类成员)

2 A class is considered a completely-defined object type (3.9) (or complete type) at the closing } of the class specifier . 2在类说明符的结尾 } 处,类被认为是完全定义的对象类型 (3.9)(或完整类型) 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).在类成员规范中,类在函数体、默认参数、引入继承构造函数的 using 声明(12.9)、异常规范和非静态数据成员的括号或相等初始化器中被视为完整的(在嵌套类中包括这些东西)。 Otherwise it is regarded as incomplete within its own class member-specification.否则在它自己的类成员规范中被认为是不完整的。

So in this declaration所以在这个声明中

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

where the data member c is declared the structure is not yet a complete type.其中声明了数据成员c的结构还不是完整的类型。 So the compiler does not know what is the size of the data member c .所以编译器不知道数据成员c的大小。 So the compiler is unable to generate the definition of the structure.所以编译器无法生成结构的定义。

From the C Standard (6.2.5 Types)来自 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). ...在翻译单元内的各个点,对象类型可能不完整(缺乏足够的信息来确定该类型对象的大小)或完整(具有足够的信息)。

On the other hand, pointers are always complete types.另一方面,指针总是完整的类型。 Their sizes are always known.它们的尺寸总是已知的。

From the C Standard (6.2.5 Types)来自 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''.从引用类型 T 派生的指针类型有时称为“指向 T 的指针”。 The construction of a pointer type from a referenced type is called ''pointer type derivation''.从引用类型构造指针类型称为“指针类型派生”。 A pointer type is a complete object type .指针类型是一个完整的对象类型

Pay attention to that your programs are not C programs because C does not have the header <iostream> .请注意,您的程序不是 C 程序,因为 C 没有标题<iostream> You showed C++ programs.你展示了 C++ 程序。

Nevertheless the quotes I provided are valid also for C++.尽管如此,我提供的引号也适用于 C++。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM