简体   繁体   English

编译错误,“使用未定义的结构”

[英]Compilation error, “uses undefined struct”

I want to forward-declare the parts of a struct, so the "package" struct is first shown.我想向前声明结构的各个部分,因此首先显示“包”结构。 I'm getting an error of "use of undefined struct" where "Header" is declared in "Package".我收到“使用未定义结构”的错误,其中“包”中声明了“标题”。 Surely the compiler (VS2010) would scan the header file for the definition before throwing this error?在抛出此错误之前,编译器(VS2010)肯定会扫描定义的头文件吗?

struct Header;

struct Package
{
    Header header;             <-- "uses undefined struct"

};

struct Header
{
    uint32_t Signature;
    uint8_t MajorVersion;
    uint8_t MinorVersion;
};

Thanks谢谢

I'm getting an error of "use of undefined struct" where "Header" is declared in "Package".我收到“使用未定义结构”的错误,其中“包”中声明了“标题”。

You can't declare a member of an incomplete type , because the compiler doesn't know how big it is and how much space should it reserve for it (among other things).你不能声明一个不完整类型的成员,因为编译器不知道它有多大以及它应该为它保留多少空间(除其他外)。

Surely the compiler (VS2010) would scan the header file for the definition before throwing this error?在抛出此错误之前,编译器(VS2010)肯定会扫描定义的头文件吗?

No, what makes you think that?不,是什么让你这么想?

You cannot use the type until it has been fully declared, since information such as the size etc. needs to be known beforehand.在完全声明类型之前,您不能使用该类型,因为需要事先知道诸如大小等信息。 You can, however, make pointers to these types, since they do not require this information.但是,您可以创建指向这些类型的指针,因为它们不需要此信息。


There are two ways to resolve this.有两种方法可以解决这个问题。 A cheaty one and a "proper" one.一个作弊的和一个“适当的”。

First the cheaty one.第一个骗子。 You can prototype a struct, however, you can only use the struct as a pointer until you declare it.您可以对结构进行原型设计,但是,在声明之前,您只能将该结构用作指针。 So you cannot use Header as a value type before it has been declared.因此,您不能在声明之前将Header用作值类型。 So the cheaty way would be replacing Header header;所以作弊的方法是替换Header header; with Header *header;Header *header; and then allocate memory at runtime.然后在运行时分配内存。

There is, however, a much, much nicer way.然而,还有一种更好的方法。

You could split this single file into multiple files, namely: header.hpp and package.hpp , and have them include eachother.您可以将此单个文件拆分为多个文件,即: header.hpppackage.hpp ,并让它们相互包含。 However, there is one problem when doing this.但是,这样做时存在一个问题。 When the headers recursively include eachother (or you include the same header multiple times), the types will be redifined over and over again.当标题递归地包含彼此(或者您多次包含相同的标题)时,类型将一遍又一遍地重新定义。 You need a way to only define the types once.您需要一种方法来只定义一次类型。 This is done almost every time a header is used, by enclosing it with "inclusion guards".几乎每次使用标题时都会这样做,通过用“包含守卫”将其括起来。 It looks like so:它看起来像这样:

#ifndef HEADER_HPP
#define HEADER_HPP

// Header code here

#endif /* HEADER_HPP */

That way, they'll only be declared once, but you can use both types in both files.这样,它们只会被声明一次,但您可以在两个文件中使用这两种类型。

So your package.hpp file will look like this:所以你的package.hpp文件将如下所示:

#ifndef PACKAGE_HPP
#define PACKAGE_HPP

#include "header.hpp"

struct Package {
    Header header;
};

#endif

And your header.hpp will look like this:您的header.hpp将如下所示:

#ifndef HEADER_HPP
#define HEADER_HPP

struct Header {
    uint32_t Signature;
    uint8_t MajorVersion;
    uint8_t MinorVersion;
};

#endif

You can't have Package contain something of type Header when the compiler doesn't yet know what exactly Header is.当编译器还不知道 Header 到底是什么时,你不能让 Package 包含 Header 类型的东西。 You can only have pointers to Header.您只能拥有指向 Header 的指针。

You can use pointers:您可以使用指针:

struct Package
{
    struct Header *header;
};

struct Header
{
    uint32_t Signature;
    uint8_t MajorVersion;
    uint8_t MinorVersion;
};

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

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