#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.
> 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/009695399/functions/dlsym.html
--
mail1dotstofanetdotdk
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
> 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 && m...@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