8

Afaik uintptr_t and intptr_t can be used to hold any pointer to void. Hence these types can be used to store pointers to data.

In C99 or later, are there similar signed and unsigned integer types capable of holding pointers to functions?

jotik
  • 17,044
  • 13
  • 58
  • 123
  • There is no single "pointer to function" type (each type depends on the function prototype). – barak manos Apr 04 '16 at 13:16
  • You cannot even convert a function pointer to a `void *`. Also C and C++ are different languages. Please restrict your question to one of them. – too honest for this site Apr 04 '16 at 13:19
  • @barakmanos True, but each pointer-to-function type can store any other pointer-to-function type after conversion, so if you have an integer type large enough for one pointer-to-function type, you should have an integer type large enough for all of them. –  Apr 04 '16 at 13:19
  • 1
    @Olaf You can convert it to a sufficiently large integer type though. It's just that there's no guarantee that any integer type is sufficiently large. –  Apr 04 '16 at 13:20
  • @hvd: Yes, found it myself. I was really sure they used the term "object pointer" there, too. Sorry for the confusion. I removed my comments. – too honest for this site Apr 04 '16 at 13:28

1 Answers1

13

No, there are no such types.

Function pointers may only be reliably cast to other function pointer types (and then, only dereferenced while pointing to the correct function type).

The conversion of function pointers to integers in C is covered by 6.3.2.3/6:

Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.

Note that even if the integer type is large enough, casting to integer and back to function pointer is not guaranteed to retrieve the original function pointer.

In C++, the text is in [expr.reinterpret.cast] points 4 and 6. The behaviour is similar, but it explicitly guarantees that if an integer of sufficient size exists, then converting function pointer to integer and back again does retrieve the original function pointer.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • 1
    Just to add that an implementation has to specify _implementation defined_ behaviour. So one should be able to find if and how such a conversion is valid for a specific implementation. This may be done by an ABI, not necessarily in the compiler. A similar conversion might be possible between `void *` and a function pointer (see J.5.7). – too honest for this site Apr 04 '16 at 13:33
  • Just to inform other readers: J.5 in the C standard is a section about common extensions to the C language in the *informative* (not normative) Annex J about portability issues. – jotik Apr 04 '16 at 13:43
  • You could make the conversion reliable: `_Static_assert(sizeof(uintptr_t) >= sizeof(func_pointer_t), "bleh");`. Then such conversions will only fail on obscure systems where pointers are something different than addresses (IMO such systems deserve to crash anyhow.) – Lundin Apr 06 '16 at 14:08
  • 2
    @Lundin: Just because function pointers and other pointers are of different sizes does not mean that pointers are "something different than addresses". Not every machine is a Von Neumann one (in fact, since embedded CPUs far outnumber desktop ones *and* since x86 is technically not Von Neumann to boot [it's a hybrid], I'd argue *most* systems are not Von Neumann). In embedded, function pointers are often larger than other ones (that said, they're often --- but NOT always --- padded to the same type anyways in C). – Tim Čas Jun 12 '16 at 20:59
  • @TimČas the standard even specifically says that addresses are pointers. (C11 6.5.3.2/3). I guess the "pointers aren't addresses" crowd actually mean "pointers aren't integers" which is ironic in a way. – M.M Jun 12 '16 at 21:06
  • @M.M: All I'm saying is that just because `sizeof(void (*)(void))` and `sizeof(void*)` can be different does not mean they aren't addresses. And it also does not mean you can just cast/convert one to the other (you can in practice in x86 [POSIX, for example, explicitly states that the cast is well-defined], but as I said, not on Harvard-architecture systems, since function pointers typically point to program memory, while "normal" ones point to RAM). – Tim Čas Jun 15 '16 at 11:24
  • @TimČas yes,I'm agreeing with you – M.M Jun 15 '16 at 11:27