我如何解释这个看似函数声明但不符合通常模式的声明?

How do I interpret this declaration that appears to be a function declaration, but doesn't fit the usual mould?

我正在尝试破译来自 sqlite3.c

的声明
SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void);

好像是在声明一个函数,因为后面还有这个

SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
  return pVfs->xDlSym(pVfs, pHdle, zSym);
}

然后似乎是对函数的调用

xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry);

xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry);

但我无法理解该声明。我突出显示了我无法理解的地方

SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void);
                    ^                                                    ^^^^^^^

我想知道为什么声明不是这样

SQLITE_PRIVATE void *sqlite3OsDlSym(sqlite3_vfs *, void *, const char *);

我预计可能已经有人问过类似的问题,但搜索 ()void 等术语并没有真正找到任何结果。所以,如果这是一个骗局,我很乐意将其关闭。

这是在声明一个 return 是函数指针的函数。 return 类型是 void (*)(void)SQLITE_PRIVATE 扩展为 static 并且不是 return 类型的一部分,根据评论),但是函数名称(和参数) 必须出现在 (*) 部分内。

函数和数组是需要做体操来解析的两个C类型类别。您可以将数组类型和函数类型视为 "decorating" 它们描述的标识符。如果您写 int foo,则表示符号 "foo" 具有整数类型。如果您写 int foo(double),则表示符号 foo(double) 具有整数类型。 foo(double) 必须粘在一起,所以任何进一步的修饰都必须将整个东西包裹起来,就好像它是一个名字一样。

这一点最好通过混合数组类型和函数类型来说明,即使结束类型在 C 中可能不合法。(这充分说明了语法的荒谬程度。)例如:

int foo[5](double)

将是函数 (int ... (double)) 的数组 (foo[5])。另一方面:

int foo(double)[5]

是一个函数 (foo(double)),return 是一个数组 (int ... [5])。

外部资源 cdecl.org 可以帮助您理解这种声明。但是,您需要将结构名称替换为标准类型(或将结构类型写为 struct sqlite_vfs 而不是 sqlite_vfs),以便它理解您的声明。

这个声明

SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void);

是 return 类型函数的声明,它是

类型的函数指针
void ( * )( void )

可以通过引入typedef来简化声明。例如

typedef void ( *FP )( void );

SQLITE_PRIVATE  FP sqlite3OsDlSym(sqlite3_vfs *, void *, const char *);

这是一个演示程序,它使用了一个类似的函数,return是指向另一个函数的指针。

#include <stdio.h>

typedef void ( *FP )( void );

void h( void )
{
    puts( "Hello World" );
}

FP f( void );
void ( *f( void) )( void )
{
    return h;
}

int main(void) 
{
    f()();

    return 0;
}

它的输出是

Hello World

首先函数 f 是使用 typedef 声明的,然后没有使用 typedef

FP f( void );
void ( *f( void) )( void )
{
    return h;
}