nullprogram.com/blog/2010/02/18/
Here's something I only learned recently, since it came up when
working on Wisp. In C function
pointers are incompatible with normal pointers. For example, this is
unportable C,
This is because function pointers are a different size than other
pointers on some architectures, or even within the same architecture
with different models (x86's compact and medium models). If the
compiler in such a scenario allowed this, the pointer may be truncated
and would likely point to the wrong place. It wasn't until I added
the -pedantic
flag to gcc that it started warning me
about situations like the above. The -W -Wall
flags are
silent here.
The relevant part of
the ANSI C
standard lists the following as a common, but unportable,
extension to the language,
A pointer to an object or to void may be cast to a pointer to a
function, allowing data to be invoked as a function. A pointer to
a function may be cast to a pointer to an object or to void,
allowing a function to be inspected or modified (for example, by a
debugger).
There is a discussion, including an example, on Stack
Overflow:
Can the Size of Pointers Vary Depending on what's Pointed To?. It
also links to this comp.lang.c FAQ
question Question
4.13 suggesting the use of a union, which is exactly what I did in
Wisp.
I bet this issue only comes up very rarely. How often do you have to
store a function pointer in a void pointer? It subverts the type
system and is generally a bad idea. I had to do it in Wisp as part of
its value polymorphism, which is why it bit me. This is probably why
gcc doesn't get very picky over it.
This also means function pointers have less support than normal
pointers. For example, printing pointers
with printf()
's %p
won't work, since it
expects a void
pointer, so there's no printing them. You
can't sort them with qsort()
. You can even treat the
function pointer as a blob of data to manipulate manually since
there's no safe way to make a regular pointer to it. Really, almost
any C library function that accepts pointers won't work with function
pointers.
So if you want a tricky, unfair, interview question this could be
one!