undefined C struct forward declaration

2019-01-14 07:37发布

问题:

I have a header file port.h, port.c, and my main.c

I get the following error: 'ports' uses undefined struct 'port_t'

I thought as I have declared the struct in my .h file and having the actual structure in the .c file was ok.

I need to have the forward declaration as I want to hide some data in my port.c file.

In my port.h I have the following:

/* port.h */
struct port_t;

port.c:

/* port.c */
#include "port.h"
struct port_t
{
    unsigned int port_id;
    char name;
};

main.c:

/* main.c */
#include <stdio.h>
#include "port.h"

int main(void)
{
struct port_t ports;

return 0;
}

Many thanks for any suggestions,

回答1:

Unfortunately, the compiler needs to know the size of port_t (in bytes) while compiling main.c, so you need the full type definition in the header file.



回答2:

If you want to hide the internal data of the port_t structure you can use a technique like how the standard library handles FILE objects. Client code only deals with FILE* items, so they do not need (indeed, then generally can't) have any knowlege of what is actually in the FILE structure. The drawback to this method is that the client code can't simply declare a variable to be of that type - they can only have pointers to it, so the object needs to be created and destroyed using some API, and all uses of the object have to be through some API.

The advantage to this is that you have a nice clean interface to how port_t objects must be used, and lets you keep private things private (non-private things need getter/setter functions for the client to access them).

Just like how FILE I/O is handled in the C library.



回答3:

A common solution that I use:

/* port.h */
typedef struct port_t *port_p;

/* port.c */
#include "port.h"
struct port_t
{
    unsigned int port_id;
    char name;
};

You use the port_p in function interfaces. You will need to create special malloc (and free) wrappers in port.h as well:

port_p portAlloc(/*perhaps some initialisation args */);
portFree(port_p);


回答4:

I would recommend a different way:

/* port.h */
#ifndef _PORT_H
#define _PORT_H
typedef struct /* Define the struct in the header */
{
    unsigned int port_id;
    char name;
}port_t;
void store_port_t(port_t);/*Prototype*/
#endif

/* port.c */
#include "port.h"
static port_t my_hidden_port; /* Here you can hide whatever you want */
void store_port_t(port_t hide_this)
{
    my_hidden_port = hide_this;
}

/* main.c */
#include <stdio.h>
#include "port.h"
int main(void)
{
    struct port_t ports;
    /* Hide the data with next function*/
    store_port_t(ports);
    return 0;
}

It is generally no good to define variables in a header file.