简体   繁体   中英

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 ):

typedef struct _httpc_state httpc_state_t;

The library defines the struct in the implementation ( 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:

/** 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 ).

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 . 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. 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.

In the translation unit where the function rec_fn is defined the compiler sees only the following declaration

typedef struct _httpc_state httpc_state_t;

It knows nothing about whether the data member timeout_ticks used in this statement

req->timeout_ticks = 30;

is indeed declared within the structure struct _httpc_state and what is its type. That is the name timeout_ticks is undeclared in this translation unit. 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. [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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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