Hi Martin, On 2026-05-15T16:05:24+0200, Martin Uecker wrote: > > There is no such thing needed here, you just do > > double (*cosine)(double); > > cosine = dlsym(handle, "cos"); Hmmmm, yes. I don't know why the manual page uses a cast in the POSIX version. The above wouldn't be enough in ISO C, since void* isn't guaranteed to work with function pointers. However, any systems where dlsym(3) works must support holding function pointers in void* (because otherwise, dlsym(3) itself wouldn't work), so ISO C shouldn't be a concern at all. Hmmm; I'll simplify the page. Thanks! Have a lovely day! Alex > > > Best, > Martin > > Am Freitag, dem 15.05.2026 um 11:56 +0200 schrieb Alejandro Colomar: > > Hi Walter, > > > > On 2026-05-15T08:35:49+0000, Walter Harms wrote: > > > Hello, > > > I agree the cast is not nice, (someone for a extension of C standard ?) > > > but i have to admit that i have never seen the trick with the union. > > > But it needs some explaination. The comment in the example is already huge, > > > i would ask for a comment subsektion for this behavier here. > > > > The thing about unions is that the only two ways for type punning that > > are blessed by ISO C are unions and memcpy(3). Everything else isn't > > allowed. > > > > Perfectly valid: > > > > static_assert(sizeof(int) == sizeof(float)); > > > > union u {int i; float f;}; > > > > float f; > > union u u; > > > > u.i = 42; > > f = u.f; > > > > Perfectly valid: > > > > static_assert(sizeof(int) == sizeof(float)); > > > > int i; > > float f; > > > > i = 42; > > memcpy(&f, &i, sizeof(float)); > > > > UB: > > > > static_assert(sizeof(int) == sizeof(float)); > > > > int i; > > float f; > > > > i = 42; > > f = *(float *) &i; > > > > > > Have a lovely day! > > Alex > > > > > btw: the original code in the example looks like this ... > > > cosine = (typeof(double (double)) *) dlsym(handle, "cos"); > > > > > > my2c > > > wh > > > > > > ________________________________________ > > > Von: Alejandro Colomar > > > Gesendet: Donnerstag, 14. Mai 2026 13:29:20 > > > An: Bruno Haible > > > Cc: linux-man@vger.kernel.org; Martin Uecker > > > Betreff: Re: clumsy cast in dlopen.3 > > > > > > Hi Bruno, > > > > > > On 2026-05-14T12:56:55+0200, Bruno Haible wrote: > > > > The dlopen.3 man page contains this text: > > > > > > > > *(void **) &cosine = dlsym(handle, "cos"); > > > > > > > > This (clumsy) cast conforms with the ISO C standard and will > > > > avoid any compiler warnings. > > > > > > > > However, such a cast violates the strict aliasing rules of ISO C, no? > > > > > > I think I agree. Dereferencing the pointer &cosine with a type > > > different than the type of the object is not allowed. I've CCed Martin, > > > who might be able to confirm. > > > > > > > > > > > The proper workaround is to use a union: > > > > > > > > union { double (*cosine) (double); void *pointer; } u; > > > > > > > > u.pointer = dlsym(handle, "cos"); > > > > ... > > > > printf("%f\n", u.cosine(2.0)); > > > > > > This is seems much better, indeed. > > > > > > > > > Have a lovely day! > > > Alex > > > > > > > > > > > Bruno > > > > > > > > > > > > > > > > > > > > > > -- > > > --