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