At 02:21 AM 6/17/2009 +0300, Antti Kantee wrote:
If you have typedef struct foo foo_t; and use foo_t * in an interface,
you must always expose the implementation struct foo since you cannot
typedef twice.
With all respect, this is not true. The following pattern works well.
1) You put "typedef struct foo foo_t;" in a header file named
"foo_type.h", and #include that in every header file where you want
foo_t to be used as a forward type (i.e., where you need to use foo_t *).
2) Then in the header file ("foo.h") where you define the contents
of struct foo, you also #include "foo_type.h" before you define the contents.
(MCCI actually uses slightly different names, and we of course group
all the forward structures for a single API into a
"{module}_types.h" header file; but this illustrates the idea.)
Files that include "foo_type.h" (including the header files that
define prototypes) don't see the implementation unless they include
"foo.h" explicitly.
This works well. It's portable to every C compiler I've come across
(dozens, and not just GCC). Compile speeds are not noticeably
affected -- our products that use this technique already have
roughly a thousand header files (for other reasons) and this has
caused problems.