简体   繁体   English

typedef 结构导致“不允许不完整类型的指针”错误

[英]typedef struct leads to “pointer to incomplete type not allowed” error

I am using a library which contains the following declaration in its header ( http_client.h ):我使用的库在其标头 ( http_client.h ) 中包含以下声明:

typedef struct _httpc_state httpc_state_t;

The library defines the struct in the implementation ( http_client.c )该库在实现中定义了结构 ( http_client.c )

typedef struct _httpc_state
{
  struct altcp_pcb* pcb;
  ip_addr_t remote_addr;
  u16_t remote_port;
  int timeout_ticks;
  struct pbuf *request;
  struct pbuf *rx_hdrs;
  u16_t rx_http_version;
  u16_t rx_status;
  altcp_recv_fn recv_fn;
  const httpc_connection_t *conn_settings;
  void* callback_arg;
  u32_t rx_content_len;
  u32_t hdr_content_len;
  httpc_parse_state_t parse_state;
#if HTTPC_DEBUG_REQUEST
  char* server_name;
  char* uri;
#endif
} httpc_state_t;

In that same C file, it implements the following function, which uses the struct:在同一个 C 文件中,它实现了以下使用结构体的函数:

/** http client tcp poll callback */
static err_t
httpc_tcp_poll(void *arg, struct altcp_pcb *pcb)
{
  /* implement timeout */
  httpc_state_t* req = (httpc_state_t*)arg; // Here the void pointer is casted to httpc_state_t
  LWIP_UNUSED_ARG(pcb);
  if (req != NULL) {
    if (req->timeout_ticks) { // Here the concrete type is used. Works. No problems.
      req->timeout_ticks--;
    }
    if (!req->timeout_ticks) {
      return httpc_close(req, HTTPC_RESULT_ERR_TIMEOUT, 0, ERR_OK);
    }
  }
  return ERR_OK;
}

I have a C++ file which uses this library, and of course includes the required header ( http_client.h ).我有一个使用这个库的 C++ 文件,当然包括所需的头文件 ( http_client.h )。

extern "C"
{
    #include "FreeRTOS.h"
    #include "task.h"
    #include "semphr.h"

    #include "lwip/tcpip.h"
    #include "lwip/apps/http_client.h"  // Here I include their http_client.h file

    #include "projdefs.h"
}

In my next function, I need to do exactly what their implementation does.在我的下一个函数中,我需要完全按照他们的实现做。 I need to do something with httpc_state_t .我需要对httpc_state_t I implemented their callback function as follows:我实现了他们的回调函数如下:

err_t rec_fn(void *arg, struct altcp_pcb *conn, struct pbuf *p, err_t err)
{
    if (p)
    {
        httpc_state_t* req = (httpc_state_t*)arg; // Compiler sees no problems in casting to my desired type....
        req->timeout_ticks = 30; // COMPILE ERROR, pointer to incomplete class type _httpc_state is not allowed 
    }
}

Why am I getting that compile error?!为什么我会收到那个编译错误?! Header file is included.包括头文件。 Header files declares the typedef.头文件声明了 typedef。 Even after reading this and this , I still don't see what I am doing wrong....即使在阅读了这个这个之后,我仍然不明白我做错了什么......

Incomplete type means its declared but not defined.不完整类型意味着它已声明但未定义。 You need to define that struct in the header file and include it into your C file.您需要在头文件中定义该结构并将其包含在您的 C 文件中。

In the translation unit where the function rec_fn is defined the compiler sees only the following declaration在定义函数rec_fn的翻译单元中,编译器只能看到以下声明

typedef struct _httpc_state httpc_state_t;

It knows nothing about whether the data member timeout_ticks used in this statement它对这条语句中使用的数据成员timeout_ticks是否一无所知

req->timeout_ticks = 30;

is indeed declared within the structure struct _httpc_state and what is its type.确实在结构struct _httpc_state声明了它的类型。 That is the name timeout_ticks is undeclared in this translation unit.即名称timeout_ticks在此翻译单元中未声明。 So the compiler issues an error.所以编译器会报错。

If you are going to use data members of the structure in a translation unit then the compiler needs to know their declarations.如果您打算在翻译单元中使用结构的数据成员,那么编译器需要知道它们的声明。 That is you need also to include the structure definition.也就是说,您还需要包含结构定义。

Either move the structure definition in the header if you are allowed to do that or duplicate its definition in the module where your function is defined.如果允许,请在标题中移动结构定义,或者在定义函数的模块中复制其定义。

Pay attention to that if the structure definition was not placed in the header then the reason of that can be that the author of the code does not want to make it available outside his module or library.请注意,如果结构定义未放置在标题中,则原因可能是代码作者不想使其在其模块或库之外可用。

The error message is poorly worded.错误消息措辞不当。

Pointers to incomplete types are fine!指向不完整类型的指针很好! Dereferencing to a member of an incomplete type is the problem.取消引用不完整类型的成员是问题所在。

At the point where the error occurs the compiler hasn't 'seen' the full definition of the type in that translation unit.在发生错误时,编译器还没有“看到”该翻译单元中类型的完整定义。

It recognises the type, but doesn't know if the type even has a member timeout_ticks let alone how to generate code for access it.它识别类型,但不知道该类型是否有成员timeout_ticks更不用说如何生成访问它的代码了。 [Such as where the member is in relation to the start of the object.] [例如成员相对于对象开始的位置。]

Pointers to incomplete types are a useful way to reduce dependencies and code coupling.指向不完整类型的指针是减少依赖性和代码耦合的有用方法。 If code only needs to pass pointers to a type around the type can be declared (incomplete) and help with type checking but not be exposed to the full definition.如果代码只需要传递指向类型的指针,则可以声明(不完整)类型并帮助进行类型检查,但不会暴露给完整定义。

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

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