Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to format a function pointer?

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...


People also ask

How do you define a function pointer in C++?

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).

Can we have a pointer to a function?

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.

What is a function pointer write its syntax?

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.


3 Answers

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.

like image 96
caf Avatar answered Sep 27 '22 20:09

caf


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.

like image 22
Dustin Avatar answered Sep 27 '22 20:09

Dustin


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.

like image 29
dan04 Avatar answered Sep 27 '22 21:09

dan04