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

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

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("Hellonworld", UINT64_MAX, printf);
}

然而,这不适用于变量

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

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

回答

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

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

8 参数声明为“函数返回类型”应调整为“指向函数返回类型的指针”,如 6.3.2.1

所以例如这两个函数声明

void f( void( int ) );

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

声明同一个函数。

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

4 函数指示符是具有函数类型的表达式。除非它是 sizeof operator65) 或一元 & 运算符的操作数,否则类型为“函数返回类型”的函数指示符将转换为类型为“指向函数返回类型的指针”的表达式

这是一个演示程序。

#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 = %dn", x );
}

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

程序输出是

x = 10

调查程序。

注意例如这个typedef

typedef void F( int );

可以等效地重写为

void typedef F( int );


以上是具有C11标准的编译器接受的替代函数指针语法的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>