~skeeto/public-inbox

3 2

Re: Function Pointers are Special

Listeria monocytogenes <listeria@disroot.org>
Details
Message ID
<D2KDWPGWVF07.3DFGUBLBU35KI@disroot.org>
DKIM signature
pass
Download raw message
Sorry to revive such an old blog post, but it seems you've made some
erroneous claims, like:
> You can't sort function pointers with qsort().
You can sort function pointers with qsort(), since at no point do you
ever treat function pointers as data pointers, instead you treat
function pointers as data. The compare function passed to qsort()
receives pointers to function pointers, not pointers to functions. If
you've ever sorted strings with qsort(), you know you can't use strcmp()
as your compare function and need to resort to using a function like
cmpstringp() from the qsort(3) man-page:

       static int
       cmpstringp(const void *p1, const void *p2)
       {
           /* The actual arguments to this function are "pointers to
              pointers to char", but strcmp(3) arguments are "pointers
              to char", hence the following cast plus dereference. */

           return strcmp(*(const char **) p1, *(const char **) p2);
       }

I've attached a small program which sorts function pointers and will not
emit any warnings even if compiled with -pedantic, -Wall or whatever.

You also claim
> You can't 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.
which is wrong for a similar reason: you can take a pointer to the
function pointer (say `int (**p)()`), cast it to `char *` and treat it
as a blob of data of size sizeof(int (*)()). Unless you were refering to
treating the function data as a blob of data, in which case you'd be
right.

Re: Function Pointers are Special

Details
Message ID
<20240708200046.dha2tcujirvwz7h6@nullprogram.com>
In-Reply-To
<D2KDWPGWVF07.3DFGUBLBU35KI@disroot.org> (view parent)
DKIM signature
missing
Download raw message
If there's anything wrong with my statements it's that they weren't strong 
enough. I followed up 6 years later with a more general post:

You Can't Always Hash Pointers in C
https://nullprogram.com/blog/2016/05/30/

Though this stuff is hypothetical and not worth pontification. Nearly all 
implementations have straightforward pointer representations, and the 
practical, interesting issues involve pointer provenance, which the 
standard barely touches.

> You can sort function pointers with qsort() [...] instead you treat 
> function pointers as data

As far as the standard is concerned, this will not necessarily work, and 
pointers, object or function, are not meaningfully sortable. There are few 
constraints regarding pointer representation. Two pointers comparing equal 
with == may have memory representations that compare unequal with memcmp 
(ignored bits, etc.). The sorted array may not correspond with ==, and 
certainly not less-than and greater-than (which are undefined behavior 
anyway).

> I've attached a small program which sorts function pointers

That's a clever workaround, but it's not really sorting pointers. It's 
sorting by array index, with a terribly inefficient lookup to map pointers 
onto indices. Per the above article, there's no way to improve the lookup 
in a conforming program due to a lack of pointer semantics required for 
map building.

In practice, you'd just depend on implementation-defined behavior and call 
it a day, making the exercise here academic.

> take a pointer to the function pointer (say `int (**p)()`), cast it to 
> `char *`

The standard explicitly says that it is undefined behavior if a "pointer 
to a function is converted to a pointer to an object" making this cast 
forbidden. POSIX requires object/function pointer compatibility due to 
dlsym, and so C implementations on POSIX must define the behavior, making 
it defined in practice even beyond POSIX. But as far as C is concerned 
it's non-conforming to rely on any particular cast behavior.

Re: Function Pointers are Special

Listeria monocytogenes <listeria@disroot.org>
Details
Message ID
<D2KQQURS6N3O.2DFK9PCUO6FLF@disroot.org>
In-Reply-To
<20240708200046.dha2tcujirvwz7h6@nullprogram.com> (view parent)
DKIM signature
pass
Download raw message
> You Can't Always Hash Pointers in C
> https://nullprogram.com/blog/2016/05/30/

That's an interesting follow up, especially the part about memset and
calloc. I've always considered pointer-type members in a struct obtained
from calloc() to be NULL, but I guess they technically need to be
initialized.

> The standard explicitly says that it is undefined behavior if a
> "pointer to a function is converted to a pointer to an object" making
> this cast forbidden.

I think you're confusing converting a "pointer to a function to a
pointer to an object" with converting a "pointer to a pointer to a
function (which to my knowledge already is a pointer to an object) to a
pointer to a character type", which you can do just fine if you're just
interpreting the bytes of the object (§6.3.2.3¶7).

Re: Function Pointers are Special

Listeria monocytogenes <listeria@disroot.org>
Details
Message ID
<D2L202HMPYZR.1KER47JY5EDGC@disroot.org>
In-Reply-To
<20240708200046.dha2tcujirvwz7h6@nullprogram.com> (view parent)
DKIM signature
pass
Download raw message
In any case, the reason you don't get a meaningful value when
interpreting the bytes from function pointers is not that "Function
Pointers are Special", but rather that the bytes from a
function/object/void pointer have no meaningful value, it's the same
reason why "You Can't Always Hash Pointers in C."
Reply to thread Export thread (mbox)