How to print cascaded names of functions pointers? - c

I was working of functions pointers examples and I developed 4 simple functions and assigned them to a function pointer array, then I ran the code and worked for the 4 functions, but then I thought to also print the names of the functions.
I learned about __func__ and it only prints the name of the current function, so is there anyway to assign __func__ to the function pointer or another method to print the names of the functions?
This is the example I'm working on right now:
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
int add(int x, int y);
int sub(int x, int y);
int mul(int x, int y);
int divide(int x, int y);
int main() {
int m = 6;
int n = 10;
int res,i;
int (*fun[4])(int,int)={add,sub,mul,divide};
for (i=0;i<4;i++)
{
printf("result of %s operation\n",__func__=fun[i]);
}
}
int add(int x, int y) {
int result = x + y;
return result;
}
int sub(int x, int y) {
int result = x - y;
return result;
}
int mul(int x, int y) {
int result = x * y;
return result;
}
int divide(int x, int y) {
int result = x / y;
return result;
}
As you can see I'm trying to assign the __func__ to the functions pointer but of course it's not working.

The __func__ constant in every function is only accessible in runtime. Meaning that if you want to use that one, you have to grab it while calling the function. Like this:
typedef int calc_func_t (int x, int y, const char** func);
int add(int x, int y, const char** func);
...
calc_func_t* fun[4] = {add,sub,mul,divide};
for (i=0;i<4;i++)
{
const char* func;
int result = fun[i](1,1,&func);
printf("result of %s operation %d\n", func, result);
}
...
int add(int x, int y, const char** func)
{
int result = x + y;
*func = __func__;
return result;
}
...
If you wish to know what the functions are named at compile-time and then later on use that information, the easiest and best way would be to create a look-up table:
typedef struct
{
calc_func_t* func;
const char* name;
} calc_func_info_t;
const calc_func_info_t func_info [] =
{
{add, "add"},
{sub, "sub"},
...
};

Compiled code doesn't contain functions and symols names by default. You can use some macros to create constant strings containing functions names to be included in the compiled binary:
#include <stdio.h>
// function call type
typedef void fn_call();
// record describing one function
typedef struct fn_record {
const char *name; // function's name as a constant string
fn_call *call; // function call
} fn_record;
// the functions to be called and named
void fna() { printf("called fna\n"); }
void fnb() { printf("called fnb\n"); }
void fnc() { printf("called fnc\n"); }
// macro, that generates record for each function, it creates
// string like { "fna", fna } to save You typing
#define FN_RECORD(f) { #f, f }
// now define array of functions records
fn_record fns[3] = {
FN_RECORD(fna),
FN_RECORD(fnb),
FN_RECORD(fnc)
};
// ... which becomes:
// fn_record fns[3] = {
// { "fna", fna },
// { "fnb", fnb },
// { "fnc", fnc }
// };
int main(void) {
int i;
// ... use it whatever You like
for (i = 0; i < 3; i++) {
printf("%s\n", fns[i].name);
fns[i].call();
}
return 0;
}

Basically, there is no way.
// A function declaration
void MyFunction(void);
// a pointer to the function
void (*fnPointer)(void) = MyFunction;
// No way to retrieve function name "MyFunction" from fnPointer
Ofcourse, if you have a known set of possible functions that might be assigned to the pointer, you could compare them explicitely.
Also, you can change the stored function pointer to be combined with the function name. Could be something similar to the following:
struct FunctionPointerContainer
{
void (*fnPointer)(void);
char* fnName;
};
#define MakeFunctionPointer(fn) FunctionPointerContainer { fn, #fn }
// later
struct FunctionPointerContainer myPointer = MakeFunctionPointer(MyFunction);
myPointer.fnPointer(); // call
myPointer.fnName; // the function name

I was working of functions pointers examples
So, as I understand, your example is done for educational purposes, aren't you? In that case I would do it as simple as it can be to not confuse the students who use your example to learn how function pointers work.
I learned about __func__ and it only prints the name of the current function
Despite other answers show very nice and smart solutions how to have the function name outside of it, from the perspective of simplicity I would still use the __func__ as it normally works, inside the called function:
#include <stdio.h>
#define print_info(format, ...) \
printf("Function '%s' is called with parameters: "format"\n", \
__func__, __VA_ARGS__)
int add(int x, int y);
int sub(int x, int y);
int mul(int x, int y);
int divide(int x, int y);
int main() {
int m = 6, n = 10, i;
int (*fun[4])(int,int) = { add, sub, mul, divide };
for (i = 0; i < 4; ++i)
printf("-- result is: %d\n", fun[i](n, m));
return 0;
}
int add(int x, int y) {
print_info("%d, %d", x, y);
return x + y;
}
int sub(int x, int y) {
print_info("%d, %d", x, y);
return x - y;
}
int mul(int x, int y) {
print_info("%d, %d", x, y);
return x * y;
}
int divide(int x, int y) {
print_info("%d, %d", x, y);
return x / y;
}

Related

How do you pass a function pointer to a function in c?

#include "stdio.h"
int add(int x, int y)
{
return x + y;
}
int withFive(int x, int (*func))
{
return (*func)(x,5);
}
int main()
{
void (*funcptr)(int) = &add;
printf("%d", withFive(10,funcptr));
return 0;
}
This code seems like it would compile based on my understanding of function pointers but there is an error that a function or function pointer isn't being passed to withFive. How should I write withFive so that the compiler will accept the argument as a function ptr?
The definition should be
int withFive(int x, int (*func)(int, int ) )
or
int withFive(int x, int (*func)(int x, int y) )
like in a variable definition.
Btw: void (*funcptr)(int) = &add; should be int (*funcptr)(int,int) = &add; as well or just int (*funcptr)(int,int) = add;
int withFive(int x, int (*func))
You want, as an argument, a function func that returns int and takes two int as parameter.
So you need:
int withFive(int x, int (*func)(int, int))
Then:
{
return (*func)(x,5);
}
You don't need to dereference func. Just write
return func(x, 5);
Then:
void (*funcptr)(int) = &add;
That's the wrong type again. And you don't need to take the address of add. Just write:
int (*funcptr)(int, int) = add;
Or you could just write:
printf("%d", withFive(10,add));
Generally speaking, to make handling the somewhat awkward function pointer syntax easier and the result more readable, you could use a typedef. All together, and some other minor edits included:
#include <stdio.h>
typedef int (*binary_func_t)( int, int );
int add( int x, int y )
{
return x + y;
}
int withFive( int x, binary_func_t func )
{
return func( x, 5 );
}
int main()
{
printf( "%d\n", withFive( 10, add ) );
return 0;
}
In your case it would have to be int withFive(int x, int (*func)(int,int)). However, using the raw function pointer syntax of C is quite unreadable. The recommended practice is to always use typedefs, like this:
typedef int operation_t (int x, int y); // function type acting as "template"
int add (int x, int y);
int withFive(int x, operation_t* op); // op is a pointer to function
...
withFive(10, add);

Function that returns a pointer to function using parameter passed

I'm a bit confused as to how to implement the following. I want to have a function, func2, return a function that with call func1 with the specified parameters:
int func1(int x, int y, int z, int type){
// Calculations
}
int ((*func2)(int x, int y, int z))(int type){
// Return a pointer to func1 that with get x, y, z as parameters
// when called later, with type = type being fixed
}
Use:
my_func = func2(3);
printf("result = %d\n", my_func(1,2,3));
For this to work you need something called a closure which is basically a record with the function and the type as fields. Below is an example to illustrate the idea. In a real program you also need to check that malloc doesn't return NULL, and free the memory.
#include <stdio.h>
#include <stdlib.h>
typedef struct ClosureDesc *Closure;
struct ClosureDesc {
int type;
int (*function)(Closure c, int x, int y, int z);
};
int func1(Closure c, int x, int y, int z)
{
return c->type;
}
Closure func2(int type)
{
Closure c;
c = malloc(sizeof *c);
c->type = type;
c->function = func1;
return c;
}
int main(void)
{
Closure my_func;
my_func = func2(3);
printf("result = %d\n", my_func->function(my_func, 1,2,3));
return 0;
}
Function pointers syntax is a bit confusing but you can make it easier typedefing the functions itself. Then you can use "normal" pointer syntax.
typedef int func(int,int,int);
int func1(int x, int y, int z){
// Calculations
return 1;
}
int func2(int x, int y, int z){
// Calculations
return 2;
}
int func3(int x, int y, int z){
// Calculations
return 3;
}
func *selectfunc(int type)
{
func *f = NULL;
switch(type)
{
case 1:
f = func1;
break;
case 2:
f = func2;
break;
case 3:
f = func3;
break;
}
return f;
}
int main(void)
{
int type = rand()%3;
printf("%d", selectfunc(type)(1,2,3));
}
or
func *fptr = selectfunc(2);
fptr(1,2,3);
Here’s what I think you’re going for:
int func1( int x, int y, int z )
{
...
}
/**
* func2 takes an integer parameter and returns a
* pointer to a function that takes 3 integer
* parameters and returns int
*/
int (*func2(int type))(int, int, int)
{
/**
* This example is based on what you wrote in your
* question. Regardless of how you actually select
* which function to return based on the input, the
* return statement will be the same.
*/
switch ( type )
{
case 3:
return func1;
break;
default:
break;
}
return NULL;
}
int main( void )
{
int (*my_func)(int, int, int);
...
my_func = func2( 3 );
if ( my_func )
printf( "result = %d\n", my_func( 1, 2, 3 ) );
...
}
If you write func2 such that it can never return NULL and you want your co-workers to throw things at you, you can dispense with the my_func variable and just write
printf( "result = %d\n", func2(3)(1, 2, 3));
I wouldn’t recommend it though, unless you like rude comments in code reviews.

How do functions with a function pointer as an argument accept it if it is uninitialized?

How does the function pointer in the declaration of any_function receive any value? In the main function, any_function is never given any function pointers, only functions themselves. Does this mean the function pointer any_function is recursively calling itself?
#include <stdio.h>
int sum(int, int);
int product(int, int);
int difference(int, int);
int any_function(int(*pfun)(int, int), int x, int y);
int main(void)
{
int a = 10; /* Initial value for a */
int b = 5; /* Initial value for b */
int result = 0; /* Storage for results */
int (*pf)(int, int) = sum; /* Pointer to function */
/* Passing a pointer to a function */
result = any_function(pf, a, b);
printf("\nresult = %d", result );
/* Passing the address of a function */
result = any_function(product,a, b);
printf("\nresult = %d", result );
printf("\nresult = %d\n", any_function(difference, a, b));
return 0;
}
/* Definition of a function to call a function */
int any_function(int(*pfun)(int, int), int x, int y)
{
return pfun(x, y);
}
/* Definition of the function sum */
int sum(int x, int y)
{
return x + y;
}
/* Definition of the function product */
int product(int x, int y)
{
return x * y;
}
/*Defintion of the function product*/
int difference(int x, int y)
{
return x - y;
}
How does the function pointer in the declaration of any_function receive any value?
Because the function call specified a value. Same as any other parameter.
E.g. when you write:
int my_function(int x) {
return x + 1;
}
// in main
printf("%d\n", my_function(5));
it prints 6. But how did x in the declaration of my_function receive any value? Well, it was specified when we wrote my_function(5).
In the main function, any_function is never given any function pointers, only functions themselves.
If you use a function like that it is converted to a pointer automatically. In other words pf = sum; is short for pf = ∑
Does this mean the function pointer any_function is recursively calling itself?
No, where did that idea come from?

how can I return values of any type in C?

i need get some logs from uses of variables in C code;
For example from the following code:
int main(){
int a,b,c;
a=1;
b=1;
c= a==0||b==1
return 0;
}
i make:
int log(int v){
//print log
return v;
}
int main(){
int a,b,c;
a=1;
b=1;
c= log(a)==0||log(b)==1
return 0;
}
this work perfectly, but with all variables int.
how can i do this for variable of any type?
#include <stdio.h>
#define LOG(TYPE, STRING, VAR) \
(printf(STRING, VAR), (TYPE) VAR)
int main()
{
int j = 3;
double q = 2.3;
double s;
s = LOG(int, "j=%d\n", j) + LOG(double, "q=%lf\n", q);
LOG(double, "s=%lf\n", s);
}
j=3
q=2.300000
s=5.300000
One caution: This evaluates the VAR expression twice, so it should always be the contents of a regular variable, not a more complex expression. You can replace the call to printf with a call to a logging operation that uses varargs.
Log4c is your friend:
Log4c is a library of C for flexible logging to files, syslog and other destinations. It is modeled after the Log for Java library (http://jakarta.apache.org/log4j/), staying as close to their API as is reasonable. Here is a short introduction to Log4j which describes the API, and design rationale.
how can i do this for variable of any type?
To switch code based on various types, use _Generic() to select type specific functions.
int log_int(int v) {
printf("(int %d)\n", v);
return !!v;
}
int log_double(double v) {
printf("(double %e)\n", v);
return !!v;
}
int log_char_ptr(char *v) {
printf("(str %s)\n", v);
return !!v;
}
#define mylog(X) _Generic((X), \
int: log_int, \
double: log_double, \
char *: log_char_ptr \
)(X)
Now code only needs to call mylog(various_types).
int main(void) {
int i = 3;
double d = 4.0;
char *s = "5";
mylog(i)==0||mylog(d)==0||mylog(s)==0;
return 0;
}
Output
(int 3)
(double 4.000000e+00)
(str 5)

How to pass a function as a parameter?

How is it possible to give a function (B) a function (A) as a parameter?
So that I can use function A in the function B.
Like the Variable B in the following example:
foo(int B) { ... }
By using function pointers. Look at the qsort() standard library function, for instance.
Example:
#include <stdlib.h>
int op_add(int a, int b)
{
return a + b;
}
int operate(int a, int b, int (*op)(int, int))
{
return op(a, b);
}
int main(void)
{
printf("12 + 4 is %d\n", operate(12, 4, op_add));
return EXIT_SUCCESS;
}
Will print 12 + 4 is 16.
The operation is given as a pointer to a function, which is called from within the operate() function.
write function pointer type in another function's parameter list looks a little weird, especially when the pointer is complicated, so typedef is recommended.
EXAMPLE
#include <stdio.h>
typedef int func(int a, int b);
int add(int a, int b) { return a + b; }
int operate(int a, int b, func op)
{
return op(a, b);
}
int main()
{
printf("%d\n", operate(3, 4, add));
return 0;
}
Lets say you have a function you want to call:
void foo() { ... }
And you want to call it from bar:
void bar(void (*fun)())
{
/* Call the function */
fun();
}
Then bar can be called like this:
bar(foo);

Resources