c - C11 标准编译器接受的替代函数指针语法

标签 c function-pointers typedef implicit-conversion function-declaration

我不确定这个函数指针类型声明语法,但它有效。语法就像声明一个常规的旧函数一样。

typedef struct Element GetChildCallback(void *userdata, usize parent, usize child_no);

我找不到任何有关它如何符合标准或它可能有哪些缺点的信息。

我认为这只适用于 typedef,所以我更进一步,发现这也适用于常规函数参数:

extern inline void dmpstrn(const char *t, usize n, int printer(const char *fmt, ...));

inline void dmpstrn(const char *t, usize n, int printer(const char *fmt, ...)) {
    usize len = strlen(t) > n ? n : strlen(t);
    printer("\"");
    for (usize i = 0; i < len; i += 1) {
        if (t[i] == '\n') 
            printer("\\n");
        else
            printer("%c", t[i]);
    }
    printer("\"\n");
}

// ...

int main() {
    dmpstrn("Hello\nworld", UINT64_MAX, printf);
}

但这不适用于变量

    int printer(const char *fmt, ...) = printf; // Invalid

就好像它不是函数指针,而是实际的函数,但这是什么意思?

最佳答案

用作函数参数的函数声明由编译器隐式调整为指向函数类型的指针。

摘自 C 标准(6.7.6.3 函数声明符(包括原型(prototype)))

8 A declaration of a parameter as ‘‘function returning type’’ shall be adjusted to ‘‘pointer to function returning type’’, as in 6.3.2.1

例如这两个函数声明

void f( void( int ) );

void f( void ( * )( int ) );

声明相同的函数。

另一方面(6.3.2.1 左值、数组和函数指示符)

4 A function designator is an expression that has function type. Except when it is the operand of the sizeof operator65) or the unary & operator, a function designator with type ‘‘function returning type’’ is converted to an expression that has type ‘‘pointer to function returning type’’

这是一个演示程序。

#include <stdio.h>

typedef void F( int );

F display;

void g( F );

void g( F *f )
{
    int x = 10;
    
    f( x );
}

void display( int x )
{
    printf( "x = %d\n", x );
}

int main(void) 
{
    F *fp = display;
    
    g( fp );
    
    return 0;
}

程序输出为

x = 10

调查该程序。

注意这一点,例如这个 typedef

typedef void F( int );

可以等效地重写为

void typedef F( int );

关于c - C11 标准编译器接受的替代函数指针语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68681763/

相关文章:

c - 尝试将 32 位代码移植到 64 位平台时出现内存错误

Golang,带有值接收器的函数的函数指针,在第二次调用时不会使用更改的接收器调用该函数

c++ - 当函数必须访问其他成员时,如何将 lambda 函数分配给结构成员?

c - GCC:使用 -Wcast-qual 将 const 指针转换为数组 typedef 的 const 指针会抛出警告

c++ - struct 定义中的 typedef 用法

C - 初始化指针数组

C 查询字符串解析

c - 如何递归地unifdef

c++ - 类似于 C++ 中的 Objective-C KVO

c++ - Typedef 更改行为导致错误和警告