如何打印函数指针的级联名称?

How to print cascaded names of functions pointers?

我正在处理函数指针示例,我开发了 4 个简单函数并将它们分配给一个函数指针数组,然后我 运行 代码并为这 4 个函数工作,但后来我想也打印函数的名称。

我了解了 __func__ 并且它只打印当前函数的名称,那么有没有将 __func__ 分配给函数指针或其他方法来打印函数名称的方法?

这是我现在正在处理的示例:

#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;
}

如您所见,我正在尝试将 __func__ 分配给函数指针,但当然它不起作用。

基本上没有办法

// A function declaration
void MyFunction(void);

// a pointer to the function
void (*fnPointer)(void) = MyFunction;

// No way to retrieve function name "MyFunction" from fnPointer

当然,如果您有一组已知的可能分配给指针的函数,您可以明确地比较它们。

另外,您可以将存储的函数指针更改为与函数名组合。可能类似于以下内容:

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

编译后的代码默认不包含函数和符号名称。您可以使用一些宏来创建常量字符串,其中包含要包含在已编译二进制文件中的函数名称:

#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;
}

每个函数中的 __func__ 常量只能在运行时访问。这意味着如果你想使用那个,你必须在调用函数时抓住它。像这样:

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;
}

...

如果您想在编译时知道函数的名称,然后在以后使用该信息,最简单和最好的方法是创建一个查找 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"},
  ...
};

I was working of functions pointers examples

因此,据我了解,您的示例是出于教育目的,对吗?在那种情况下,我会尽可能简单地做到这一点,以免混淆使用您的示例来学习函数指针如何工作的学生。

I learned about __func__ and it only prints the name of the current function

尽管其他答案显示了如何在其外部使用函数名称的非常​​好的和聪明的解决方案,从简单性的角度来看我仍然会使用 __func__ 作为它通常在被调用函数中工作:

#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;
}