C 在sqlite中找不到实际结构

C 在sqlite中找不到实际结构,c,sqlite,C,Sqlite,我正在sqlite3源代码中搜索“struct sqlite3_stmt”的完整定义,但在任何地方都找不到。我被难住了 我唯一找到的是:typedef struct sqlite3\u stmt sqlite3\u stmt 这是什么C魔法?此链接:介绍SQLite3中的特定实现,这是一篇有趣的文章 我将从C语言的角度描述这里发生的事情 如果你写: struct sqlite3_stmt; 您告诉编译器有一个名为sqlite3\u stmt的结构存在于您的翻译单元或另一个库中。如果存在匹配定义

我正在sqlite3源代码中搜索“struct sqlite3_stmt”的完整定义,但在任何地方都找不到。我被难住了

我唯一找到的是:typedef struct sqlite3\u stmt sqlite3\u stmt

这是什么C魔法?

此链接:介绍SQLite3中的特定实现,这是一篇有趣的文章

我将从C语言的角度描述这里发生的事情

如果你写:

struct sqlite3_stmt;
您告诉编译器有一个名为
sqlite3\u stmt
的结构存在于您的翻译单元或另一个库中。如果存在匹配定义,则该符号将在链接时解析

请注意,编译器不知道其大小,因此只能作为指针访问,如下所示:

struct sqlite3_stmt * ptr_totstmt; /* OK */
但是,这会给您一个错误:

struct sqlite3_stmt stmt; /* error: storage size of 'stmt' isn't known */
此外,必须在指针声明前面加上关键字
struct
,否则编译器无法解析符号:

sqlite3_stmt * ptr_totstmt; /* error: unknown type name 'sqlite3_stmt' */
这里的
typedef
的目的是添加语法糖,这样类型的用户就不必关心他是否在使用结构

typedef struct sqlite3_stmt sqlite3_stmt;

sqlite3_stmt * ptr_totstmt; /* OK */
因此,实际上,对于编译器来说,
struct sqlite3_stmt
sqlite3_stmt
是两件不同的事情,后者是前者的别名

这里的“魔力”在于,只要
struct sqlite3_stmt
类型或其别名仅用于实例化指针,就不需要知道其大小,只需要知道目标系统的指针大小。链接器实际上甚至不费事尝试解析它们,因为指针只不过是表示内存中地址的值

因此,在这里,
struct sqlite3\u stmt
从未在sqlite3的代码中的任何地方实现过,它只是作为一个指针进行访问,并转换为实现所需的任何“真实”类型。

此链接:介绍sqlite3中的特定实现,这是一篇有趣的文章

我将从C语言的角度描述这里发生的事情

如果你写:

struct sqlite3_stmt;
您告诉编译器有一个名为
sqlite3\u stmt
的结构存在于您的翻译单元或另一个库中。如果存在匹配定义,则该符号将在链接时解析

请注意,编译器不知道其大小,因此只能作为指针访问,如下所示:

struct sqlite3_stmt * ptr_totstmt; /* OK */
但是,这会给您一个错误:

struct sqlite3_stmt stmt; /* error: storage size of 'stmt' isn't known */
此外,必须在指针声明前面加上关键字
struct
,否则编译器无法解析符号:

sqlite3_stmt * ptr_totstmt; /* error: unknown type name 'sqlite3_stmt' */
这里的
typedef
的目的是添加语法糖,这样类型的用户就不必关心他是否在使用结构

typedef struct sqlite3_stmt sqlite3_stmt;

sqlite3_stmt * ptr_totstmt; /* OK */
因此,实际上,对于编译器来说,
struct sqlite3_stmt
sqlite3_stmt
是两件不同的事情,后者是前者的别名

这里的“魔力”在于,只要
struct sqlite3_stmt
类型或其别名仅用于实例化指针,就不需要知道其大小,只需要知道目标系统的指针大小。链接器实际上甚至不费事尝试解析它们,因为指针只不过是表示内存中地址的值


因此,在这里,
struct sqlite3\u stmt
从来没有在sqlite3的代码中的任何地方实现过,它实际上只是作为一个指针进行访问,并转换到实现所期望的任何“真实”类型。

它可能是一个不透明类型,因此它的定义将在某个C源文件中,而不是在头文件中。它可能是一个不透明类型,因此,它的定义将在某个C源文件中,而不是在头文件中。