Use of void * for information hiding is a very poor idea because you lose type checking. For example, the differ function in section 1.5 can easily be misused without any diagnostic:
int x, y, a[3];
/*...*/
differ("foo", "bar");
differ(&x, &y);
differ(a, a);
differ(&a, &a);
Do not hide so much information that even the compiler is left in the dark!
To not reveal anything about how an object is implemented, use a pointer to an incomplete struct, like
To not reveal anything about how an object is implemented, use a pointer to an incomplete struct, like