2017-08-15 64 views
8

我试图从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并没有真正得到任何地方。所以,如果这是一个愚蠢的行为,我会很高兴它被关闭。

回答

7

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

函数和数组是两种需要做体操解析的C类类别。您可以将数组类型和函数类型视为“装饰”它们描述的标识符。如果您编写int foo,则表示符号“foo”具有整数类型。如果您编写int foo(double),则表示符号foo(double)具有整数类型。 foo(double)必须粘在一起,所以任何进一步的装饰必须包装整个事物,就好像它是单个名称一样。

int foo[5](double) 

点是最好的混合阵列类型和函数类型,即使在C.结束类型可能不合法(这说了很多关于语法如何可笑的是),例如图示

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

int foo(double)[5] 

是一个函数(foo(double))并返回一个阵列(int ... [5])。外部资源cdecl.org可以帮助你理解这种声明。但是,您需要将结构名称替换为标准类型(或者将结构类型写为struct sqlite_vfs而不是sqlite_vfs),以便了解您的声明。

+0

谢谢,我试过cdecl.org声明,但不能让它给我以外的任何东西“语法错误”。我现在可以看到那是因为它不识别'sqlite3_vfs'。如果我只是用'int'替换'sqlite3_vfs',那么我会得到我的答案。 –

+0

另一件让我想起来的事情是,尽管'sqlite3OsDlSym'返回“指向函数(void)返回void的指针”,实际返回的函数指针具有不同的原型,因此'(sqlite3_loadext_entry)'强制转换。 –

+0

取决于'SQLITE_PRIVATE'实际是什么,它可能适用于被声明的函数而不是返回类型(例如,如果它是'static'的宏) –

2

此声明

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

是具有返回类型是类型

void (*)(void) 

声明可以通过引入一个typedef被简化的函数指针的函数的声明。例如

typedef void (*FP)(void); 

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

这里是使用了类似的函数返回一个指针到另一个功能的示范方案。

#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; 
}