Is there any way to print a pointer to a function in ANSI C? Of course this means you have to cast the function pointer to void pointer, but it appears that's not possible??
#include <stdio.h>
int main() {
int (*funcptr)() = main;
printf("%p\n", (void* )funcptr);
printf("%p\n", (void* )main);
return 0;
}
$ gcc -ansi -pedantic -Wall test.c -o test
test.c: In function 'main':
test.c:6: warning: ISO C forbids conversion of function pointer to object pointer type
test.c:7: warning: ISO C forbids conversion of function pointer to object pointer type
$ ./test
0x400518
0x400518
It's "working", but non-standard...
We declare the function pointer, i.e., void (*ptr)(char*). The statement ptr=printname means that we are assigning the address of printname() function to ptr. Now, we can call the printname() function by using the statement ptr(s).
You can use pointers to call functions and to pass functions as arguments to other functions. You cannot perform pointer arithmetic on pointers to functions.
1) Unlike normal pointers, a function pointer points to code, not data. Typically a function pointer stores the start of executable code. 2) Unlike normal pointers, we do not allocate de-allocate memory using function pointers. 3) A function's name can also be used to get functions' address.
The only legal way to do this is to access the bytes making up the pointer using a character type. Like this:
#include <stdio.h> int main() { int (*funcptr)() = main; unsigned char *p = (unsigned char *)&funcptr; size_t i; for (i = 0; i < sizeof funcptr; i++) { printf("%02x ", p[i]); } putchar('\n'); return 0; }
Examining the bytes of the function pointer with an lvalue of type void *
, or any non character type, is undefined behaviour.
What those bytes making up the function pointer actually mean is implementation-dependent. They could just represent an index into a table of functions, for example; or they could even be the first N characters of the function's name which is looked up in the symbol table when you call through the function pointer. The only operations that need be supported on a function pointer are calling the function through it and comparison against another function pointer or NULL for strict equality/inequality, so there is very wide latitude available in how they are implemented.
There's the use of unions that can get around the warning/error, but the result is still (most likely) undefined behavior:
#include <stdio.h> int main (void) { union { int (*funcptr) (void); void *objptr; } u; u.funcptr = main; printf ("%p\n", u.objptr); return 0; }
You can compare two function pointers (e.g. printf ("%i\n", (main == funcptr));
) using an if statement to test whether they're equal or not (I know that completely defeats the purpose and could very well be irrelevant), but as far as actually outputting the address of the function pointer, what happens is up to the vendor of your target platform's C library and your compiler.
Cast the function pointer to an integer, then cast it to a pointer again to use "%p".
#include <stdio.h>
int main() {
int (*funcptr)() = main;
printf("%p\n", (void *)(size_t) funcptr);
printf("%p\n", (void *)(size_t) main);
return 0;
}
Note that on some platforms (e.g. 16-bit DOS in the "medium" or "compact" memory models), pointers to data and pointers to functions are not the same size.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With