Casting when using dlsym()

前端 未结 2 2327
闹比i
闹比i 2021-02-20 14:24

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

2条回答
  •  日久生厌
    2021-02-20 15:21

    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.

提交回复
热议问题