【问题标题】:Function Definition/Declaration Using Function Pointer `typedef` in C在 C 中使用函数指针 `typedef` 的函数定义/声明
【发布时间】:2021-06-27 13:50:17
【问题描述】:

更新:

这只是一些愚蠢的事情。几分钟后我的电脑崩溃了,重新启动后它会抛出与其他所有人相同的错误......即使我使用 GIT 回到原始版本也是如此。我猜PC的RAM中有些东西搞砸了?呵呵

在C语言中,可以使用函数指针类型来声明和定义函数吗?

我做错了,但它按预期工作,没有发出任何警告:

init.h:

typedef bool (*InitFunc)(void);

init.c:

#include <init.h>
#include <moduleX.h>

InitFunc initFuncs[N];

bool init(void)
{    
    ...

    initFuncs[n] = &moduleX_Init;

    ...
}

bool initTask(void* Args)
{

    initFuncs[n]();

}

moduleX.h:

#include <init.h>

InitFunc moduleX_Init(void);

moduleX.c:

#include <moduleX.h>

InitFunc moduleX_Init(void)
{
    
    ...
        
    return true;
}

如您所见,我使用函数指针的typedef 定义了函数moduleX_Init。它使用 GCC (arm-none-eabi-gcc) 编译,甚至没有警告并按预期工作。

我只是错误地这样做了,但是当我注意到它时,我想知道这是否实际上是一种声明函数的合规方式,或者它恰好适用于 GCC。

编辑:

如果我像这样InitFunc moduleX_Init; 进行声明,则会收到以下错误:

分配给类型 InitFunc {aka _Bool 时的类型不兼容 (*)(void)}' 来自类型 '_Bool'

因此,当在变量声明中使用时,函数指针类型就像返回类型的typedef 一样工作。这是标准行为,还是只是 GCC 的特殊性?

【问题讨论】:

  • 不能在不同类型的函数指针之间赋值。这不符合 C 语言。您可以通过显式强制转换来做到这一点,但您仍然必须使用正确的类型调用函数。
  • 为什么moduleX_Init 不只返回一个bool

标签: c syntax typedef function-declaration function-definition


【解决方案1】:

不,您不能使用函数指针 typedef 来声明或定义函数。你可以使用 use 来使用函数指针 typedefs 来指定返回值和参数的类型。

您正在声明 moduleX_Init 返回一个函数指针。那是你想要的吗? @SergeyA 已经给了你分配的警告,这是你得到的 moduleX_Init 警告(gcc 8.3.0-6,除了输入文件没有任何参数):

1.c: In function ‘moduleX_Init’:
1.c:6:9: warning: returning ‘int’ from a function with return type ‘InitFunc’ {aka ‘_Bool (*)(void)’} makes pointer from integer without a cast [-Wint-conversion]                                                                            
  return true;
         ^~~~

【讨论】:

    【解决方案2】:

    您的代码格式错误,编译时不可能没有警告。这是我用你的代码得到的:

    <source>: In function 'init': <source>:11:18: warning: assignment to 'InitFunc' {aka '_Bool (*)(void)'} from incompatible pointer type '_Bool (* (*)(void))(void)' [-Wincompatible-pointer-types]
    

    你的声明

    typedef bool (*InitFunc)(void);
    
    InitFunc moduleX_Init(void);
    

    声明一个返回函数指针的函数。它本身并没有什么问题,但是当您尝试像这样使用它时:

    initFuncs[n] = &moduleX_Init;
    

    您正在分配具有不兼容签名的函数指针,因为 initFuncs[n] 的类型为 bool (*)(void)

    【讨论】:

    • 是的,我也是这么想的。但我没有收到任何警告。
    • 也很奇怪,因为,我怎么会有这样的函数返回函数指针呢?
    • @Cerike 一点也不奇怪。函数是 C 中的一等公民,因此您可以从函数返回指向它们的指针,就像返回指向任何其他类型的指针一样。有时,此类函数称为高阶函数。
    • 这不是我的意思,我的意思是它很奇怪,它对我来说是这样的,因为这样,我不能让一个函数返回一个函数指针。
    • @Cerike 不确定您的意思。当然,您不能让函数返回指向函数的指针,只是在需要返回 bool 的函数时无法使用它。
    【解决方案3】:

    在C语言中,可以使用函数指针类型来声明和定义函数吗?

    没有。函数指针只是一个指针。你可以用它来调用函数是指向的,并且在任何情况下都可以使用指针

    我做错了,但它按预期工作,没有发出任何警告

    好吧,至于“任何警告”部分编译器不同意你的看法。对于这一行:

        typedef bool (*InitFunc)(void);
    

    clang 10编译器说

    dsp$ clang -c min.c
    min.c:2:16: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
    typedef bool (*InitFunc)(void);
                   ^
    min.c:2:9: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
    typedef bool (*InitFunc)(void);
    ~~~~~~~ ^
    min.c:2:14: error: function cannot return function type 'int (void)'
    typedef bool (*InitFunc)(void);
                 ^
    2 warnings and 1 error generated.
    

    gcc 9.3

    dsp$ gcc -c min.c
    min.c:2:15: error: expected declaration specifiers or ‘...’ before ‘*’ token
        2 | typedef bool (*InitFunc)(void);
          |               ^
    

    至于“按预期工作”部分,您的期望是什么?

    另一个类似的typedef

    typedef int(*Pfri)(int);
    

    这是相当常见的东西,将名称 Pfri 声明为 functionfunction 并返回 int 并将 int 作为参数,这一次编译器会很高兴.

    使用 this 的 C 示例

    #define N 10
    #include    <stdio.h>
    
    typedef int(*Pfri)(int);
    
    int plus3(int i) { return i*3; };
    int plus4(int i) { return i*4; };
    
    int main(void)
    {
        Pfri    initFunc[N];
        printf("fills array of function pointers\n");
        for( int i = 0; i<N; i+=2 )
            initFunc[i] = plus4, initFunc[1+i] = plus3;
        printf("\
    For odd indexes, function is \"int plus3(int i) { return i*3; };\"\n\
    For even  indexes, function is \"int plus4(int i) { return i*4; };\"\n\
    Array has %d functions\n", N);
        for( int i=0; i<N; i+=1 )
            printf("f(%d)=%d\n", i,initFunc[i](i) );
        return 0;
    }
    

    这个程序:

    • 采用上述 typedef 并声明它们的数组。
    • 声明了 2 个与此类型定义名称兼容的函数
    • 用指向函数的指针填充数组
    • 调用每一个并显示结果

    输出

    fills array of function pointers
    For odd indexes, function is "int plus3(int i) { return i*3; };"
    For even  indexes, function is "int plus4(int i) { return i*4; };"
    Array has 10 functions
    f(0)=0
    f(1)=3
    f(2)=8
    f(3)=9
    f(4)=16
    f(5)=15
    f(6)=24
    f(7)=21
    f(8)=32
    f(9)=27
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      相关资源
      最近更新 更多