Exposing only void pointers in an API
api, c, void
Solution
The reason to hide the types behind `void` pointers could be a (misguided) attempt to hide (in the sense of modular programming) the internal details. This is dangerous, as it throws any type checking the compiler might do right out the window.
Better would be something along the lines:
`for-user.h`:
struct internalstuff;
void somefunc(struct internalstuff *p);
`for-internal-use.h`:
#include "for-user.h"
struct internalstuff { ...};
`implementation.c`:
#include "for-internal-use.h";
void somefunc(struct internalstuff *p)
{
...
}
This way nobody will mix up `internalstuff` with a random string or the raw result from `malloc(3)` without getting at least a warning. As long as you only mention pointers to `struct internalstuff` in C it is fine not to have the definition of the `struct` at hand.
Something along the same lines can be done in C++ with `class`, and I'd be suprised if Objective C doesn't allow the same. But the object oriented programming languages have their own, much more flexible, tools for this. There you can define a bare-bones base class to export, while internally extensions are used. Take a look at a good C++ book for details (there are extensive lists here).
Problem
I've seen a good deal of C libraries that do not present the objects they deal with internally as distinct types, but instead wrap them with void pointers before letting you access them. In practice, the "private" source files look something like: ``` typedef struct { int value; } object; void * object_new(void) { object *o = malloc(sizeof(object)); o->value = 1; return o; } int object_get(void *o) { return (object *)o->value; } void * object_free(void *o) { free(o); } ``` And in the main header you have only: ``` void * object_new(void); int object_get(void *o); void * object_free(void *o); ``` Now I wonder: is there a particular reason they do so? If the idea is to ensure the API user has no access to the internals of the object, isn't it sufficient to only expose the type name in the main library header, and to hide the details of the underlying structure (or whatever be the actual object) in the implementation files?