Never defined structure

后端 未结 2 1918
一整个雨季
一整个雨季 2021-02-13 20:20

Is there any benefit in having never-defined structures in C ?

Example in SQLite source code :

/* struct sqlite3_stmt is never defined */
typedef struct          


        
相关标签:
2条回答
  • 2021-02-13 20:51

    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 Vdbes (whatever they are) because that's a name that makes sense in the context of the implementation. The API talks about sqlite3_stmts 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.

    0 讨论(0)
  • 2021-02-13 20:57

    It is defined like this to hide the implementation detail of sqlite3_stmt from the user, thus avoiding the internal states from being messed around. See Opaque pointer.

    (This also forces the user only to use the type as a pointer since the structure sqlite3_stmt itself has incomplete implementation.)


    Edit: VDBE (virtual database engine) is just "a" back-end of the SQLite3 API. I believe the back-end is changeable, thus a sqlite3_stmt* is not necessarily a Vdbe*. Not exposing Vdbe* in the API because the back-end detail should not be exposed.

    0 讨论(0)
提交回复
热议问题