Let's say that there's an interface specification "X". X calls for XHeader.h
to have a struct called X_Fiddle
that guarantees the presence of members foo
and bar
, both of type int
. However, implementation-defined members are not prohibited and are in fact encouraged if doing so increases efficiency. I need to write an implementation of X for the company I work for, and realised that having a few members specific to my implementation to store some state would be very convenient, so I wrote the following:
typedef struct X_Fiddle {
int foo; /* Guaranteed by spec */
int bar; /* Guaranteed by spec */
size_t dinky_dingbat; /* IMPLEMENTATION-SPECIFIC, DO NOT USE */
unsigned char *dingbat_data; /* IMPLEMENTATION-SPECIFIC, DO NOT USE */
} X_Fiddle;
Of course, there's nothing to tell the users that dinky_dingbat
or dingbat_data
should not be used since they are implementation-specific details and may change or disappear at some point in the future. Given that I can't hide the implementation by using something like opaque pointers, what should I do to make such internal members stand out (or other tricks to hide such things)? Are there any commonly used/standard ways of dealing with problems like this? Best I could think of is using a naming convention like leading underscores, but I'm not sure if the leading underscores rules apply to member variables, and I have a feeling that I'm getting mixed up with some C++ specific rules too. I also thought of naming them something like INTERNAL_dinky_dingbat
or having a separate struct for internal types contained inside X_Fiddle
, but I'd like to keep the extra typing to a minimum so I dislike them somewhat. Or is it perfectly acceptable just to have a plain, ordinary struct as above, where implementation-specific details are spelled out in the comments and documentation, leaving the less experienced and diligent to suffer their self-inflicted wounds when I need to change things around?
Assuming I'm starting from scratch and/or my company/team has no convention for this specific case.
Even if the PIMPL idiom is C++ thing, it has actually be used for longer in plain C as anonymous void
pointers.
If you want the structure to have private implementation-specific fields, then create a structure for those private fields, and add a void
pointer field to the public structure. Then have an init
or create
function which allocates this private structure, and makes the void
pointer field in the public structure point to that private structure.