Hello Vincent, On Thu, 8 Oct 2020 at 15:52, Vincent Lefevre <vincent@xxxxxxxxxx> wrote: > > On 2020-10-01 18:55:04 +0200, Alejandro Colomar via Gcc wrote: > > On 2020-10-01 18:38, Michael Kerrisk (man-pages) wrote: > > > > +According to the C language standard, > > > > +a pointer to any object type may be converted to a pointer to > > > > +.I void > > > > +and back. > > > > +POSIX further requires that any pointer, > > > > +including pointers to functions, > > > > +may be converted to a pointer to > > > > +.I void > > > > +and back. > > > I know you are correct about POSIX, but which part of the > > > standard did you find this information in? The only > > > reference that I find in POSIX is the dlsym() spec. Is it > > > covered also somewhere else in the standrd? > [...] > > I've bean searching, and dlsym is the only one: > [...] > > The most explicit paragraph in dlsym is the following: > > > > [[ > > Note that conversion from a void * pointer to a function pointer as in: > > > > fptr = (int (*)(int))dlsym(handle, "my_function"); > > > > is not defined by the ISO C standard. > > This standard requires this conversion to work correctly > > on conforming implementations. > > ]] > > I think that "this conversion" applies only to the dlsym context, > and the conversion isn't defined in general. Imagine that the > void * pointer to function pointer conversion requires the compiler > to generate additional code. The compiler may be able to detect > that dlsym will not be used in some contexts (e.g. because of > always false condition) and do not generate such additional code, > making the conversion to have undefined behavior. Thanks. It's a good point that you raise. I agree that the wording in the standard is not too clear. But I believe the intent really is to allow [void *] <==> [function pointer] casts. The most relevant pieces I can find are as follows: In the current standard, in CHANGE HISTORY for dlsum(): [[ Issue 6 IEEE Std 1003.1-2001/Cor 1-2002, item XSH/TC1/D6/14 is applied, correcting an example, and adding text to the RATIONALE describing issues related to conversion of pointers to functions and back again. Issue 7 POSIX.1-2008, Technical Corrigendum 1, XSH/TC1-2008/0074 [74] is applied. ]] https://www.austingroupbugs.net/view.php?id=74 This is a little thin. The initial report says: "The intent is simply to permit dlsym to use a void * as its return type." and no one seems to have questioned that. And then in https://pubs.opengroup.org/onlinepubs/7899949299/toc.pdf (TC1 for POSIXX.1-2001) there is: [[ Change Number: XSH/TC1/D6/14 [XSH ERN 13] On Page: 259 Line: 8566,8590 Section: dlsym In the EXAMPLES section, change from: fptr = (int (*)(int))dlsym(handle, "my_function"); to: *(void **)(&fptr) = dlsym(handle, "my_function"); In the RATIONALE section on Page 260, Line 8590, change from: "None." to: "The C Standard does not require that pointers to functions can be cast back and forth to pointers to data. Indeed, the C Standard does not require that an object of type void* can hold a pointer to a function. Systems supporting the X/Open System Interfaces Extension, however, do require that an object of type void* can hold a pointer to a function. The result of converting a pointer to a function into a pointer to another data type (except void*) is still undefined, however. ]] And one finds the above text in POSIX.1-2001 TC1 spec for dlsym(), although it was removed in POSIX.1-2008, and now we have just the smaller text that is present in the dlsym() page. But along the way, I can find nothing that speaks against the notion that POSIX was aiming to allow the more general cast of [void *] <==> [function pointer]. Your thoughts? Thanks, Michael -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/