|
Home > Archive > Unix Programming > May 2004 > Casting dlsym return value to function pointer
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Casting dlsym return value to function pointer
|
|
| Udo Steinberg 2004-05-10, 5:44 pm |
| The following program is a shortened example for dlsym() usage from an
older manpage (error checking and such omitted):
#include <dlfcn.h>
#include <stdio.h>
int main (void) {
double (*cosine)(double);
void *handle;
handle = dlopen ("libm.so", RTLD_LAZY);
cosine = dlsym (handle, "cos");
dlclose (handle);
return 0;
}
Compiling it with gcc-3.4 the compiler complains about a bad cast:
gcc -W -Wall -pedantic -fstrict-aliasing foo.c -ldl
foo.c: In function `main':
foo.c:11: warning: ISO C forbids assignment between function pointer
and `void *'
Making the cast explicit, i.e. changing line 11 as follows:
cosine = (double (*)(double)) dlsym (handle, "cos");
yields the following compiler warning:
foo.c: In function `main':
foo.c:11: warning: ISO C forbids conversion of object pointer to
function pointer type
Newer manpages for dlsym suggest to cast the return value of dlsym as
follows:
*(void **) (&cosine) = dlsym (handle, "cos");
Now the compiler complains:
foo.c: In function `main':
foo.c:11: warning: dereferencing type-punned pointer will break
strict-aliasing rules
So my question is - how am I supposed to cast the return value of
dlsym, so that gcc-3.4 doesn't yield any warnings, when using the
following compiler flags: -W -Wall -pedantic -fstrict-aliasing
-Udo.
| |
| Bjorn Reese 2004-05-10, 5:44 pm |
| On Sun, 09 May 2004 13:18:24 -0700, Udo Steinberg wrote:
> So my question is - how am I supposed to cast the return value of
> dlsym, so that gcc-3.4 doesn't yield any warnings, when using the
> following compiler flags: -W -Wall -pedantic -fstrict-aliasing
Looks like your caught between two standards (ISO C and SUSv3).
For further information see the RATIONALE section for dlsym in
SUSv3:
http://www.opengroup.org/onlinepubs...ions/dlsym.html
--
mail1dotstofanetdotdk
| |
| Michael Kerrisk 2004-05-10, 5:44 pm |
| On Sun, 09 May 2004 22:50:39 +0200, "Bjorn Reese"
<breese@see.signature> wrote:
>On Sun, 09 May 2004 13:18:24 -0700, Udo Steinberg wrote:
>
>
>Looks like your caught between two standards (ISO C and SUSv3).
>For further information see the RATIONALE section for dlsym in
>SUSv3:
>
>http://www.opengroup.org/onlinepubs...ions/dlsym.html
Yes. The current suggested remedy is somethng like the following:
int (*funcp)(int); /* Ptr to function with 1 int arg. */
*(void **) (&funcp) = dlsym(handle, symbol);
gcc -pedantic warns that "ANSI C forbids the use of cast expressions
as lvalues" for the seemingly equivalent:
(void *) funcp = dlsym(handle, symbol);
This problem is avoided by the first technique because we are
assigning to an address pointed to by the assignment's lvalue.
Cheers,
Michael
| |
| Erik Max Francis 2004-05-10, 5:44 pm |
| Michael Kerrisk wrote:
> Yes. The current suggested remedy is somethng like the following:
>
> int (*funcp)(int); /* Ptr to function with 1 int arg. */
> *(void **) (&funcp) = dlsym(handle, symbol);
>
> gcc -pedantic warns that "ANSI C forbids the use of cast expressions
> as lvalues" for the seemingly equivalent:
>
> (void *) funcp = dlsym(handle, symbol);
>
> This problem is avoided by the first technique because we are
> assigning to an address pointed to by the assignment's lvalue.
No, you meant:
funcp = (int (*)(int)) dlsym(...);
The cast on the left-hand side is functionally useless and actually
creates a second problem (the result of a cast is not an lvalue).
(Note that in C++ you can't use a reinterpret_cast, since that's
explicitly forbidden for conversion between function pointers and data
pointers; you must use the old-style C cast.)
--
__ Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
/ \ San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
\__/ I would have liked to have seen Montana.
-- Capt. Vasily Borodin
|
|
|
|
|