我在sqlite 3源代码中搜索“struct sqlite3_stmt”的完整定义,但无法在任何地方找到它。我很难过!
我发现的只有:typedef struct sqlite3_stmt sqlite3_stmt;
这是什么C法术?
答案 0 :(得分:1)
这个链接:Never defined structure解决了SQLite3中的特定实现,是一个有趣的读物。
我将从C语言的角度描述这里发生的事情。
如果你写:
struct sqlite3_stmt;
您告诉编译器,您的翻译单元或其他库中存在名为sqlite3_stmt
的结构。如果存在匹配的定义,该符号将在链接时解析。
请注意,编译器不知道 size ,因此它只能作为指针访问,如下所示:
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_stmt
从未在SQLite3的代码中的任何地方实现,它只是作为指针实际访问并转换为实现所期望的任何“真实”类型。