Sujet : Re: Casting the return value of ...
De : 433-929-6894 (at) *nospam* kylheku.com (Kaz Kylheku)
Groupes : comp.lang.cDate : 28. Mar 2024, 19:16:03
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <20240328105203.773@kylheku.com>
References : 1
User-Agent : slrn/pre1.0.4-9 (Linux)
On 2024-03-28, Kenny McCormack <
gazelle@shell.xmission.com> wrote:
But here's the thing. Is the casting of the result of dlsym()
[to a function pointer type] necessary?
Isn't this the same as "casting the return value of malloc()", where you
Conversions between function pointers and data pointers are an
extension; it is not well-defined behavior in ISO C.
Therefore we can neither say that ISO C doesn't require a cast there (it
imposes no requirements at all), nor that the conversion is fine with a
cast.
The cast is /likely/ necessary, in order to correctly trigger the
extension.
But here's where it gets interesting. In the man page for dlopen(), we
find this example code and a long detailed comment:
The "Linux Programmer's Manual" man pages are often lacking in
technical precision, and even contain rants (see regex(7)).
*(void **) (&cosine) = dlsym(handle, "cos");
>
This (clumsy) cast conforms with the ISO C standard and will
avoid any compiler warnings.
It does not conform! The address of a pointer-to-function object is
type punned to look like a "void *", and assigned.
It breaks aliasing rules.
It does not use the extension of converting between function and object
pointers; it's relying on punning them.
For it to be 100% correct, there has to be a compiler extension to
support the punning that it is doing, and function and object pointers
have to have the same representation.
The 2013 Technical Corrigendum to POSIX.1-2008 (a.k.a.
POSIX.1-2013) improved matters by requiring that conforming
implementations support casting 'void *' to a function pointer.
I also seem to remember something like this, but I cannot trust this
documentation without a chapter-and-verse citation.
Assuming it is true, there you have it; if you're on POSIX, the compiler
is required to have the extension and it is connected to casting,
in which case the cast is required.
And why do we even need the "clumsy" cast? Why not just:
>
cosine = dlsym(handle, "cos");
Because of the man page author's goal of eliminating a warning
from GCC.
I think there was a time in the development of GCC when there was
a warning even with the cast. I don't think it's enabled by default
now?
(I seem to recall that, a number of years ago, the GCC goofballs, in
fact, merged a change that caused the compiler to generate a run-time
abort in code that converted function/object pointers. It was turned on
by default. It had to be backpedaled due to all the screaming from
downstream distros. Am I hallucinating that?)
-- TXR Programming Language: http://nongnu.org/txrCygnal: Cygwin Native Application Library: http://kylheku.com/cygnalMastodon: @Kazinator@mstdn.ca