Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

foward typedef structures

gcc 4.4.4 c89

I have this in my header file.

port.h

struct struct_tag;

int initialize_ports(struct_tag *port);

In my implemenation file I have this:

port.c

typedef struct struct_tag {
    int port_id;
} Port_t;

And in my driver.h file, I have the following:

#include "port.h"
int initialize_ports(struct_tag *port)
{
    port = malloc(sizeof *port);
    /* do checking here */
}

I have forward declared the structure, as I want to hide the internal elements.

However, I am getting the following error on my initialize_ports in the header file:

expected ‘)’ before ‘*’ token

I am just wondering how can I forward declare and be able to pass the structure as a parameter?

Many thanks for any advice,

like image 611
ant2009 Avatar asked Dec 03 '22 04:12

ant2009


2 Answers

You should use:

int initialize_ports(struct struct_tag *port);
                     ^^^^^^

Also, forward declarations give you an incomplete type which you don't know the size of. If you need to allocate a struct struct_tag you need to include the full definition for it. Alternatively you could use some create_struct_tag() function if you want to make it fully opaque.

like image 88
Georg Fritzsche Avatar answered Dec 04 '22 18:12

Georg Fritzsche


As other answers have noted, you could change struct_tag to struct struct_tag in the prototype. Another way of getting your code to compile is to write

typedef struct struct_tag struct_tag;

in place of your existing struct struct_tag; (i.e. combine the typedef with the forward definition). That then does allow you to write

int initialize_ports(struct_tag *port)

without compile failures. However, this is still not quite what you want, because the caller can neither allocate a local variable of this type, nor malloc() one - because they don't know the size.

Other answers have suggested that you should open up the definition of the structure. That's generally not the right answer - because it removes the abstraction layer you're trying to create. Much better to have functions (in the port.c, i.e. the library that does know about the internals) such as:

struct_tag *create_port(...);
void free_port(struct_tag *port)

i.e. to create and free the structures - and indeed for other operations (such as reading from / writing to the structure) too.

like image 38
psmears Avatar answered Dec 04 '22 17:12

psmears