That's an excellent point: what if you _don't_ know what it's really
pointing to? For example, functions such as memcpy(), memmove(),
memset(), etc., are used extensively to deal with objects of any type.
So this functions take void *'s, and they might be pointing to an int,
to a char, to a structure, or anything you can think of. I'm sure the
implementor of such a function would find it enjoyable to be able to
perform void pointer arithmetic!
As someone who has actually written a number of these implementation
functions, I can answer to the last statement here (about "find[ing]
it enjoyable"): no, it really makes essentially no difference.
Here is a classic example of a linear search function (which I am
typing in "on the fly", otherwise I would show a binary search
modeled after bsearch()). Note where "void *" appears and where
it does not.
/*
* Linear search: search "nmemb" items of size "size", starting
* at "base", for the given "key". Return a pointer to the
* item found, or NULL if the item is not found.
*
* Comparisons between keys and items are done by calling the
* compar() function, which should return 0 if they match,
* nonzero otherwise.
*/
void *lsearch(const void *key, const void *base0,
size_t nmemb, size_t size,
int (*compar)(const void *, const void *)) {
const unsigned char *base = base0;
size_t i;
for (i = 0; i < nmemb; i++, base += size)
if (compar(key, base) == 0)
return (void *)base; /* cast away const */
return NULL;
}
In GNUC, where sizeof(void)==1, I can replace "const void *base0"
with "const void *base" and remove the first line of the function.
Otherwise, the entire function remains exactly the same. (The cast
on the return value is still required, as lsearch() mimicks bsearch()
and de-consts its return value.) The code generated by any reasonably
good compiler also remains the same.
(Since linear search is slow, you probably want to call bsearch()
anyway. The bsearch() code is a bit more complex, so the "extra"
line, "const unsigned char *base = base0", adds even less to the
source, percentage-wise. As I said above, I would have shown a
bsearch(), but for two things: I might get it wrong, and the
name bsearch() is reserved to the implementation.)