为啥这个结构类型“不完整”,它真的用指针解决了吗?

Posted

技术标签:

【中文标题】为啥这个结构类型“不完整”,它真的用指针解决了吗?【英文标题】:Why is this struct type "incomplete," and is it really solved with a pointer?为什么这个结构类型“不完整”,它真的用指针解决了吗? 【发布时间】:2021-04-10 08:42:33 【问题描述】:

我已经定义了这些结构。

struct http_req 
    struct http_req_line rl;


struct http_req_line 
    enum method 
        OPTIONS,
        GET,
        HEAD,
        POST,
        PUT,
        DELETE,
        TRACE,
        CONNECT
     method;
    enum uri_type 
        ASTERISK,
        ABSOLUTEURI,
        ABS_PATH,
        AUTHORITY
     uri_type;
    union req_uri 
        char asterisk[1];
        char absoluteURI[256];
        char abs_path[256];
        char authority[256];
     req_uri;
    char http_ver[16];
;

当我编译包含这个头文件的文件时(它自己编译得很好),gcc 给了我这个

request_types.h:2:23: error: field ‘rl’ has incomplete type
  struct http_req_line rl;

但是将标题的第二行更改为

struct http_req_line *rl;

摆脱了这个错误。是什么导致了这个错误,并且将该成员更改为指针真的可以解决问题,还是只是将其隐藏在编译器中?

【问题讨论】:

欢迎来到 SO。您是否尝试过使用它之前声明结构? 【参考方案1】:

在编译器看到的地方:

struct http_req 
    struct http_req_line rl;

没有关于struct http_req_line 是什么的信息。您需要 struct http_req 的结构定义出现在 struct http_req_line 的定义之后。您可以使用指针(指向不完整的类型);你不能使用结构的副本。

参见 C11 标准§6.7.2.1 Structure and union specifiers:

结构或联合不应包含不完整或函数类型的成员(因此,结构不应包含自身的实例,但可能包含指向自身实例的指针),...

【讨论】:

【参考方案2】:

在您定义struct http_req 时,struct http_req_line 是未知的。编译器不知道它有多大,也不知道它的对齐要求是什么,所以它不知道rl成员要使用多少空间,也无法完成它对struct http_req的定义。

如果您想在struct http_req 中嵌入struct http_req_line,请将struct http_req_line 的定义移到struct http_req 的定义之前。

如果您将rl 更改为指针,则该类型在C 意义上不是不完整的,因为编译器将知道指针有多大以及它的对齐要求是什么。它不需要知道它指向的结构有多大,就可以为指针rl规划空间。

【讨论】:

【参考方案3】:

您看到此错误是因为您试图在定义结构本身之前定义结构的实例。你需要先定义它,然后使用它:

struct http_req_line 
    enum method 
        OPTIONS,
        GET,
        HEAD,
        POST,
        PUT,
        DELETE,
        TRACE,
        CONNECT
     method;
    enum uri_type 
        ASTERISK,
        ABSOLUTEURI,
        ABS_PATH,
        AUTHORITY
     uri_type;
    union req_uri 
        char asterisk[1];
        char absoluteURI[256];
        char abs_path[256];
        char authority[256];
     req_uri;
    char http_ver[16];
;


struct http_req 
    struct http_req_line rl;
;

将成员类型更改为指针的原因是因为您不需要完整的结构定义来使用指向它的指针。当需要类型定义 时,该指针将被取消引用。

【讨论】:

以上是关于为啥这个结构类型“不完整”,它真的用指针解决了吗?的主要内容,如果未能解决你的问题,请参考以下文章

C语言不允许使用不完整的类型报错是啥意思啊

智能指针循环引用——你真的懂了吗?

智能指针循环引用——你真的懂了吗?

C语言 不允许使用不完整的类型

包含指向其他结构的指针的结构

你真的掌握数据结构与算法了吗?