我如何解释这个看似函数声明但不符合通常模式的声明?
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;
}
我正在尝试破译来自 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;
}