13

Background

The POSIX standard adds a lot of library functions and other identifiers to the C language. In the description of the dlsym() function, it says (with my emphasis):

SYNOPSIS

#include <dlfcn.h>

void *dlsym(void *restrict handle, const char *restrict name);

DESCRIPTION

The dlsym() function shall obtain the address of a symbol (a function identifier or a data object identifier) ...

The C standard doesn't guarantee that a function pointer can be converted to a void *, or even that the size of the pointers are the same. This effectively adds an additional restriction on C's type system.

Question

My question is this:

  • Is there a normative reference for this restriction of C's type system, or is it only deducible from the description of certain library functions?
  • Is POSIX even implementable on a system where sizeof (function pointer) > sizeof (void *)?

References

Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
  • 2
    Can you site an example of a ***system*** _where sizeof (function pointer) > sizeof (void *)?_ – ryyker Dec 30 '14 at 14:29
  • @ryyker: No. I have heard rumours about such systems, at least in the past, but I don't know of any myself. It is mostly a theoretical question for my part. – Nisse Engström Dec 30 '14 at 14:41
  • 2
    @ryyker A compiler for MS-DOS in the medium data model regime would be such an *implementation*. – n. m. could be an AI Dec 30 '14 at 15:41
  • The [POSIX `` documentation](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdarg.h.html#tag_13_45) says about exceptions where type mismatch between passed argument and how it is fetched via `va_arg` is not undefined as an XSI extension: _Both types are pointers._ Might help somewhat, though it doesn't give a satisfying answer. – mafso Dec 30 '14 at 16:32
  • 2
    @ryyker i used to work on MSP430, which is a 16-bit system. its c compiler from IAR implements function pointers with 32-bit length, while `void *` is 16-bit. the reason to have such an implementation is code can reside not only in ram, but in flash too. – Jason Hu Dec 30 '14 at 16:42
  • 1
    @ryyker : pmg can http://stackoverflow.com/questions/1473935/can-the-size-of-pointers-vary-depending-on-whats-pointed-to – Ciro Santilli OurBigBook.com Jun 26 '15 at 20:38

1 Answers1

7

The dlsym() reference says the conversion is not defined by the C standard but that a conforming implementation has to make this work correctly. So on systems where this can not be made to work would not be a conforming implementation and would presumably document this:

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.

there is an old article that talks about this from the C++ perspective and links to an older version of the dlsym() reference and has a more detailed explanation:

The ISO C standard does not require that pointers to functions can be cast back and forth to pointers to data. Indeed, the ISO C standard does not require that an object of type void * can hold a pointer to a function. Implementations supporting the XSI 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 ISO 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");

Due to the problem noted here, a future version may either add a new function to return function pointers, or the current interface may be deprecated in favor of two new functions: one that returns data pointers and the other that returns function pointers.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • 2
    "required to generate a warning". This is not true as the C standard does not have a concept of warning. – n. m. could be an AI Dec 30 '14 at 15:03
  • 1
    @n.m. well that was a a quote from the 2004 version of the reference and that language has been removed from the more recent version. I am assuming it was an editorial issue and what was really meant was diagnostic. – Shafik Yaghmour Dec 30 '14 at 15:06
  • Perhaps a simpler solution would be make `dlsym` return an `intptr_t` (and require that `intptr_t` is able to represent function pointer types). – n. m. could be an AI Dec 30 '14 at 15:27