To clarify: What you're asking is why SQLite does the above instead of doing this:
Header file:
typedef struct sqlite3_stmt sqlite3_stmt;
C file:
struct sqlite3_stmt {
/* lots of members */
};
int sqlite3_step(sqlite3_stmt *pStmt) {
/* do stuff with pStmt... */
}
(This is the canonical form of the "opaque pointer" pattern linked to in KennyTM's answer.)
The only good reason I can think of why SQLite does what it does is the following:
The backend code, I'm speculating, came before the API and used the name Vdbe
-- the name probably means something related to the implementation along the lines of "virtual database entry" (guessing wildly here).
When time came to create the API, someone realized that the parameter required by sqlite3_step
was a Vdbe
but that this was not exactly a name that would convey a lot to the user of the API. Hence, from the user's point of view, a Vdbe
is referred to as an sqlite3_stmt
.
The point here, then, is to differentiate between two views of the same item: The backend thinks in terms of Vdbe
s (whatever they are) because that's a name that makes sense in the context of the implementation. The API talks about sqlite3_stmt
s because that's a name that makes sense in the context of the interface.
Edit: As Amarghosh points out, why not just do this to achieve the same effect?
typedef struct Vdbe sqlite3_stmt;
KennyTM points out a good possible reason (please vote him up, I don't want to siphon off his rep here): VDBE is only one of several possible backends; the interface uses a "generic" sqlite3_stmt
, and this is then cast to whatever the backend uses to implement it.