exactly.
> When using the pointer to implementation idiom, wouldn't the pointer itself change the size of the struct?
yes, it will
> You've said something about that not being a problem when you add it as the last member of the struct but i don't understand why and how that would work.
usually, externals shouldn't care about the *size* the t_editor struct (at least I can't think of any use case), so you can get away with adding new fields at the end (although it's certainly not recommended). Note that those headers aren't really
public anyway!
However, appending fields conditionally can lead to problems:
struct Foo {
int a;
#ifdef FOO_EX
int c;
#endif
};
Now let's say we need to add another member:
struct Foo {
int a;
#ifdef FOO_EX
int c;
#endif
If the host compiles with FOO_EX defined and the client doesn't, the latter will assume a wrong offset for 'b'.
The solution is to add a field for private data *once*. The advantage is that a) we can hide the private data and b) we can extend it without worrying about compatibility:
struct Foo {
int a;
PrivateFoo *p;
};
We can still add public members if needed:
struct Foo {
int a;
void *private;
int b;
};
'private' points to a private data structure that is not be visible to clients. There you can conditionally enable members without problems:
struct PrivateFoo {
#ifdef USE_BAR
struct MyFeature feature;
#endif
};
MyFeature could be in a seperate source file together with your methods and it only gets compiled when needed.
Again, have a look at the "t_canvas_private" struct and the "gl_privatedata" member of "_glist" (aka "t_canvas") and do the same for "_editor", e.g.:
in g_canvas.h:
typedef struct _editor {
...
void *e_privatedata;
} t_editor;
in g_editor.c:
#ifdef HAVE_KEYBOARDNAV
#include "g_keyboardnav.h"
#endif
typedef struct _editor_private {
#ifdef HAVE_KEYBOARDNAV
t_keyboardnav keyboardnav;
#endif
} t_editor_private;
the "t_keyboardnav" struct is defined in "g_keyboardnav.h" and its methods implemented in "g_keyboardnav.c". Both only get compiled when needed.
Hope this makes sense.
Christof