c - Casting when using dlsym() -


i'm using dlsym() in c , have question whether return value of dlsym() should explicitly cast or if implicitly cast correctly. here function:

double (*(compile)(void))(double x, double y) {     if (system("scan-build clang -fpic -shared -g -wall -werror -pedantic "            "-std=c11 -o0 -lm foo.c -o foo.so") != 0) {         exit(exit_failure);     }      void *handle;     handle = dlopen("./foo.so", rtld_lazy);     if (!handle) {         printf("failed load foo.so: %s\n", dlerror());         exit(exit_failure);     }      foo f;     f = (foo)dlsym(handle, "foo");     if (!f) {         printf("failed find symbol foo in foo.so: %s\n", dlerror());         exit(exit_failure);     }     return f; } 

the function compile() not take value , returns pointer function takes 2 doubles input , returns double. set system call compiles shared object foo.so. open foo.so dlopen(). dlsym() finds foo in foo.so , returns object of type foo defined in header as:

typedef double (*foo)(double, double); 

do have cast dlsym()?

the c standard written assume pointers different object types, , pointers function opposed object types, might have different representations. that's why, in general, don't want intermix pointers, or if modern compiler warn you, , if want silence warnings typically use explicit cast.

dlsym, on other hand, existence assumes pointers pretty same, because it's supposed able return pointer datatype -- object or function -- in object file.

in other words, code uses dlsym inherently nonportable, in sense it's not portable, in sense it's portable "only" machines pointers safely interconvertible. (which of course virtually of popular machines today.)

so, yes, you'll need cast pointers silence warnings, , in doing may making code less portable machines pointers aren't same (and warnings, if unsilenced, correctly inform code won't work), dlsym never going work (or exist in current form) on machines, anyway.

(and if gcc -pedantic warns explicit cast void * function pointer type, there's not can except switch different version of gcc, or of course not use -pedantic.)


addendum: answer made sound converting between pointers different types of data might issue, that's no problem. type void * defined generic data pointer: it's malloc returns, , it's defined quietly convertible object pointer type -- is, you're not supposed need cast. it's fine choice return type of dlsym, except wee problem of function pointers. malloc never has problem (you'd hardly ever try malloc pointer function), while dlsym has problem (the symbols you're trying access in dynamically-loaded object files code @ least they're data). function pointers void * isn't guaranteed convert to, you're warnings, why need casts, , might warnings under -pedantic casts.


Comments