foward typedef structures
gcc 4.4.4 c89
I have this in my header file.
port.h
struct struct_tag;
int in开发者_Python百科itialize_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,
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.
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.
You'll get an error as you don't KNOW the size of "port" as all it has to go on is the forward declaration.
In summary you are best off not using a forward declaration here unless you also set a constant value that is the sizeof "struct_tag" ... You would most likely be best off just fully declaring it.
The sizeof
operator is evaluated at compile time not runtime, so at the line:
port = malloc(sizeof *port);
the compiler has no information regarding the size of the structure.
Solutions include:
- fully define the type in the header file.
- define
initialize_ports()
in port.c after the struct is fully defined. - have
initialize_ports()
call a function defined in ports.c to get the size ofPort_t
at run-time.
In any case you should not define initialize_ports()
in the header file driver.h unless your compiler supports the inline
or _inline
keyword and you use it. Such usage would however render the code non ISO C compliant, and therefore less portable, however due to C++'s standard support for the keyword, you are likely to find it as an extension in most C tool-chains that include C++ compilation, so long as you do not use excessively strict compliance options.
However the error message you are getting is for a different reason. Unlike C++ in C struct_tag
alone does not represent a type (if it did, you'd not have needed the typedef
!), you must use the struct
keyword.
精彩评论