I\'m using dlsym()
in C
and I have a question whether the return value of dlsym()
should be explicitly cast or if it is implicitly cast co
dlsym()
returns a void*
value. This pointer value can refer either to an object or to a function.
If it points to an object, then no cast is necessary, since C defines an implicit conversion from void*
to any pointer-to-object type:
int *ptr = dlsym(handle, "name");
If it points to a function (which is probably much more common), there is no implicit conversion from void*
to any pointer-to-function type, so a cast is necessary.
In standard C, there's no guarantee that a void*
value can meaningfully be converted to a function pointer. POSIX, which defines dlsym()
, implicitly guarantees that the void*
value returned by dlsym()
can be meaningfully converted to a pointer-to-function type -- as long as the target is of the correct type for the corresponding function.
Assuming we're dealing with a void function with no parameters:
typedef void (*func_ptr_t)(void);
func_ptr_t fptr = (func_ptr_t)dlsym(handle, "name");
As it happens, gcc (with -pedantic
) warns about this:
warning: ISO C forbids conversion of object pointer to function pointer type
This warning is not strictly correct. ISO C does not actually forbid converting an object pointer to a function pointer type. The standard lists several constraints that may not be violated by a cast operator; converting void*
to a function pointer type is not one of them. The C standard doesn't define the behavior of such a conversion, but since POSIX does in this particular case that's not a problem.
A comment on Steve Summit's answer suggests that this:
*(void **) (&f) = dlsym(handle, "foo");
will silence gcc's warning. It will, but it makes assumptions that are not guaranteed by either C or POSIX. POSIX guarantees that the result of dlsym
may be converted to a function pointer; it doesn't guarantee that it has the same representation or alignment. It's likely to work, but I don't recommend it.