问题
Suppose I have this in list.h:
typedef struct list_t list_t;
typedef struct list_iter_t list_iter_t;
list_iter_t iterator(list_t *list);
and then define them in list.c:
typedef struct node_t {
...
} node_t;
struct list_iter_t {
node_t *current;
// this contains info on whether the iterator has reached the end, etc.
char danger;
};
struct list_t {
...
}
list_iter_t iterator(list_t *list) {
list_iter_t iter;
...
return iter;
}
Is there anything I can do aside from including the struct declaration in the header file so that in some file test.c I can have:
#include "list.h"
void foo(list_t *list) {
list_iter_t = iterator(list);
...
}
Like maybe tell the compiler the storage size of list_iter_t somehow? It's inconvenient to have to use a pointer (not because it's a pointer, but for other reasons), but at the same time I would like to hide the implementation details as much as possible.
回答1:
The succinct answer is "No".
The way you tell the compiler the size of a struct
is by telling it the details of how the struct
is structured. If you want to allocate an object, rather than a pointer to the object, the compiler must know the complete type of the object. You also can't access the members of a structure via a pointer to the structure if the type is incomplete. That is, the compiler must know the offset and type of the member to generate the correct code to access someptr->member
(as well as to allocate somevalue
or access somevalue.member
).
回答2:
It is possible to tell the compiler the size of the structure, using a dummy definition like:
struct node_t {
char dummy[sizeof(struct { ... })];
};
(with the proper definition instead available to the implementation file).
Formally this causes undefined behaviour; it is likely to somewhat work in practice, though.
You are probably best off just including the proper structure definition though, and leaving a comment to the effect that code should simply not touch the internal members.
来源:https://stackoverflow.com/questions/7278495/any-way-in-c-to-forward-declare-struct-in-header-without-having-to-use-pointer-i