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?
Why do we use a void pointer in C programs? We use the void pointers to overcome the issue of assigning separate values to different data types in a program. The pointer to void can be used in generic functions in C because it is capable of pointing to any data type.
The only limitations with void pointers are: you cannot dereference void pointer for obvious reasons. sizeof(void) is illegal. you cannot perform pointer arithmetics on void pointers.
A void pointer is a pointer that can point to any type of object, but does not know what type of object it points to. A void pointer must be explicitly cast into another type of pointer to perform indirection. A null pointer is a pointer that does not point to an address. A void pointer can be a null pointer.
Because the void pointer is used to cast the variables only, So pointer arithmetic can't be done in a void pointer.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With