有没有办法检查c中两个函数是否具有相同的类型?

Per*_*ist 1 c function

例如我有这 3 个函数和函数指针:

char *(*f)(char, int);
char *(*g(char, int));
char **h(char, int);
Run Code Online (Sandbox Code Playgroud)

如果我们将它们翻译成英文,我们会得到:

  1. 将 f 声明为指向函数 (char, int) 的指针,返回指向 char 的指针

  2. 将 g 声明为函数 (char, int) 返回指向 char 的指针

  3. 将 h 声明为函数 (char, int) 返回指向 char 的指针

类型 2. 和类型 3. 是相等的。我们可以检查一下吗,也许是这样的:

if(g==h)
{
    do something;
}
Run Code Online (Sandbox Code Playgroud)

在c中?

c 也允许类似的东西吗g=h?(如果是,它实际上是做什么的?)

dbu*_*ush 6

这样的比较是有效的:

if(g==h)
Run Code Online (Sandbox Code Playgroud)

因为函数名在表达式中使用时会自动转换为函数指针,并且允许比较任意两个函数指针是否相等。在这种情况下,它将评估为 false,因为gh是两个不同的函数,因此它们的地址始终不同。

但是,您不能执行以下任一操作:

f = g;
f = h;
Run Code Online (Sandbox Code Playgroud)

因为与或f不兼容。尝试这样做可能会从编译器中生成警告:&g&h

if(g==h)
Run Code Online (Sandbox Code Playgroud)

如果您将类型更改为:

char **(*f)(char, int);
Run Code Online (Sandbox Code Playgroud)

然后它们就会兼容,你可以这样做:

f = g;
if (f==g) {   // true
    printf("f is g\n");
}
Run Code Online (Sandbox Code Playgroud)

另外,g=h也是不允许的,因为函数名称是不可修改的左值,这本质上意味着它们不能更改。

  • 我认为他想知道如何比较函数指针的类型,而不是它们是否指向同一个函数。 (2认同)

124*_*123 5

要在编译时测试类型,您可以使用带有_Generic. 我做了一个概念证明:

#include <stdio.h>

#define GETTYPE(fp) _Generic                 \
  (                                          \
    (fp)                                     \
    , char   *(*)(char,  int)         :  1   \
    , int    *(*)(char,  int)         :  2   \
    , int    *(*)(char*, int)         :  3   \
    , char  **(*)(char,  int)         :  4   \
  )

extern char  *a(char,int);
extern int   *b(char,int);
extern int   *c(char*,int);
extern char **d(char,int);

extern char  *a1(char,int);

int main(int argc, char **argv)
  {
    (void)argc;
    (void)argv;
    printf("type a %i\n",GETTYPE(a));
    printf("type b %i\n",GETTYPE(b));
    printf("type c %i\n",GETTYPE(c));
    printf("type d %i\n",GETTYPE(d));

    printf("type a==a1? %i\n",GETTYPE(a)==GETTYPE(a1));
    printf("type b==a1? %i\n",GETTYPE(b)==GETTYPE(a1));
    printf("type c==a1? %i\n",GETTYPE(c)==GETTYPE(a1));
    printf("type d==a1? %i\n",GETTYPE(d)==GETTYPE(a1));
    return 0;
  }
Run Code Online (Sandbox Code Playgroud)

GETTYPE宏将每个列出的类型转换为一个值。然后可以使用该值来存储类型并进行比较。更好的版本会使用 aenum来定义值,但您可以自己这样做。

必须在您仍然持有原始函数指针(或使用衰减为函数指针的实际函数)时调用宏。为什么这是显而易见的,但这限制了它的用例。如果要保留有关类型的信息,则需要为每个类型分配一个数字并将其存储在通用函数指针中。当需要函数指针时,可以根据类型号将其转换回原始类型。这需要大量的手工工作,因为您需要单独处理每种需要的类型。

  • @Perfectionist 这_是_比较函数类型的方法。如果太复杂,那么你就不走运了。 (2认同)