I have read that converting a function pointer to a data pointer and vice versa works on most platforms but is not guaranteed to work. Why is this the case? Shouldn't both be simply addresses into main memory and therefore be compatible?
相关问题
- Sorting 3 numbers without branching [closed]
- Multiple sockets for clients to connect to
- How to compile C++ code in GDB?
- Do the Java Integer and Double objects have unnece
- Why does const allow implicit conversion of refere
undefined doesn't necessarily mean not allowed, it can mean that the compiler implementor has more freedom to do it how they want.
For instance it may not be possible on some architectures - undefined allows them to still have a conforming 'C' library even if you can't do this.
An architecture doesn't have to store code and data in the same memory. With a Harvard architecture, code and data are stored in completely different memory. Most architectures are Von Neumann architectures with code and data in the same memory but C doesn't limit itself to only certain types of architectures if at all possible.
C++11 has a solution to the long-standing mismatch between C/C++ and POSIX with regard to
dlsym()
. One can usereinterpret_cast
to convert a function pointer to/from a data pointer so long as the implementation supports this feature.From the standard, 5.2.10 para. 8, "converting a function pointer to an object pointer type or vice versa is conditionally-supported." 1.3.5 defines "conditionally-supported" as a "program construct that an implementation is not required to support".
A modern example of where function pointers can differ in size from data pointers: C++ class member function pointers
Directly quoted from https://blogs.msdn.microsoft.com/oldnewthing/20040209-00/?p=40713/
tl;dr: When using multiple inheritance, a pointer to a member function may (depending on compiler, version, architecture, etc) actually be stored as
which is obviously larger than a
void *
.In addition to what is already said here, it is interesting to look at POSIX
dlsym()
:The only truly portable solution is not to use
dlsym
for functions, and instead usedlsym
to obtain a pointer to data that contains function pointers. For example, in your library:and then in your application:
Incidentally, this is good design practice anyway, and makes it easy to support both dynamic loading via
dlopen
and static linking all modules on systems that don't support dynamic linking, or where the user/system integrator does not want to use dynamic linking.