我如何解释这个看似函数声明但不符合通常模式的声明?
Posted
技术标签:
【中文标题】我如何解释这个看似函数声明但不符合通常模式的声明?【英文标题】:How do I interpret this declaration that appears to be a function declaration, but doesn't fit the usual mould? 【发布时间】:2018-01-23 21:13:57 【问题描述】:我正在尝试从 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
之类的术语并没有真正找到任何地方。所以,如果这是一个骗局,我会很高兴它被关闭。
【问题讨论】:
【参考方案1】:这是声明一个返回函数指针的函数。返回类型为 void (*)(void)
(SQLITE_PRIVATE
扩展为 static
,并且不是返回类型的一部分,每个 cmets),但函数名称(和参数)必须出现在 (*)
部分内。
函数和数组是需要做体操才能解析的两个C类型类别。您可以将数组类型和函数类型视为“装饰”它们所描述的标识符。如果你写int foo
,你是说符号“foo”有一个整数类型。如果你写int foo(double)
,你是说符号foo(double)
是一个整数类型。 foo
和 (double)
必须粘在一起,所以任何进一步的装饰都必须将整个东西包裹起来,就好像它是一个名字一样。
最好通过混合数组类型和函数类型来说明这一点,即使结束类型在 C 中可能不合法。(这说明了语法是多么荒谬。)例如:
int foo[5](double)
将是一个函数数组 (foo[5]
) (int ... (double)
)。另一方面:
int foo(double)[5]
是一个函数 (foo(double)
) 并返回一个数组 (int ... [5]
)。
外部资源cdecl.org 可以帮助您理解这种声明。但是,您需要将结构名称替换为标准类型(或将结构类型写为struct sqlite_vfs
而不仅仅是sqlite_vfs
)才能理解您的声明。
【讨论】:
谢谢,我尝试了 cdecl.org,但除了“语法错误”之外,它无法给我任何信息。我现在可以看到那是因为它无法识别sqlite3_vfs
。如果我只是用int
替换sqlite3_vfs
,那么我就会得到答案。
我猜想的另一件事是虽然sqlite3OsDlSym
返回“指向函数(void)返回void的指针”,但返回的实际函数指针具有不同的原型,因此(sqlite3_loadext_entry)
演员。
取决于 SQLITE_PRIVATE
的实际含义,它可能适用于被声明的函数而不是返回类型(例如,如果它是 static
的宏)
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;
【讨论】:
以上是关于我如何解释这个看似函数声明但不符合通常模式的声明?的主要内容,如果未能解决你的问题,请参考以下文章
C++ Visual Studio Windows:如何在 dll 中声明但不定义外部函数