_____________________________________________________________________________ Austin Group Interpretation reference 1003.1-2001 #003 _____________________________________________________________________________ Interpretation Number: 003 Topic: Defect in XSH dlsym Relevant Sections: dlsym Austin Group Interpretation Request: ------------------------------------ Date: Tue, 16 Apr 2002 22:40:04 +0100 (BST) ------------------------------------------------------------------------ 7 Defect Report concerning (number and title of International Standard or DIS final text, if applicable): The System Interfaces Volume of IEEE Std 1003.1-2001 ------------------------------------------------------------------------ 8 Qualifier (e.g. error, omission, clarification required): 2. Omission ------------------------------------------------------------------------ 9 References in document (e.g. page, clause, figure, and/or table numbers): Page: 259 Line: 8540 Section: dlsym XSH Enhancement Request Number 13 ------------------------------------------------------------------------ 10 Nature of defect (complete, concise explanation of the perceived problem): The "dlsym()" function is defined as returning "the address of a symbol". According to the Example, "dlsym ()can be used to access either function or data objects". The return type of dlsym is a "void *". In order to actually call a function using the pointer returned by "dlsym()", the pointer must be converted from a "void *" type to a pointer to function type. However, the ISO C Standard says that converting a "void *" type to a pointer to function type results in undefined behavior. At least one major compiler reports a warning when attempting such a conversion, even with an explicit cast. ------------------------------------------------------------------------ 11 Solution proposed by the submitter (optional): I would like a new function added that returns the address of a function object symbol and whose return type is a function pointer. For example: fptr_t dlsym_f(void *restrict handle, const char *restrict name); Standard C requires that a pointer to a function of one type may be converted to a pointer to a function of another type and back again, and the result shall compare equal to the original pointer. Therefore, "fptr_t" can be defined as any pointer to function type. The "dlsym()" function could continue to be used for data objects. As an extension, implementations that allow converting from "void *" to pointer to function types could continue to allow using "dlsym()" in addition to "dlsym_f()" for function objects. This would allow backwards compatability, while offering a more portable option for new code. ------------------------------------------------------------------------ Interpretation response ------------------------ The standard clearly states the requirements for dlsym(), and conforming implementations must conform to this. The dlsym() function is marked as part of the X/Open System Interfaces Extension (by the XSI margin marking). Systems conforming to the X/Open Systems Interfaces Extension are indeed required to be able to convert between function pointers and void * data pointers without losing data. This is most clearly stated in the description of the va_arg() macro in the description of (XBD, P310, L11109-11119) where the XSI shading on L11119 indicates that implementations supporting the X/Open System Interfaces Extension are required to be able to handle pointers to any type of object, not just pointers to data. The XSI margin marking description clearly states that requirements like this are extensions to the requirements of the C Standard. In this case, the 1999 C Standard does indeed require a warning to be issued for the function call shown in the dlsym() examples section on XSH P259, L8566. An equivalent form of this call: *(void **)(&fptr) = dlsym(handle, "my_function"); does not generate compiler warnings and will work correctly on all systems supporting the X/Open System Interfaces Extension. Rationale: ----------- See above response. Notes to the Editor (not part of this interpretation): ------------------------------------------------------- In a TC or revision of the standard make the following changes: 1. XSH P259, L8566 (EXAMPLES): Change from: fptr = (int (*)(int))dlsym(handle, "my_function"); to: *(void **)(&fptr) = dlsym(handle, "my_function"); 2. XSH P260, L8590 (RATIONALE): 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. Note that compilers conforming to the C Standard are required to generate a warning if a conversion from a void * pointer to a function pointer is attempted as in: fptr = (int (*)(int))dlsym(handle, "my_function"); Forwarded to Interpretations Group: 28 May 2002 Proposed resolution: 28 May 2002 Approved: July 9 2002