Supponiamo che una libreria C debba condividere i dettagli di una struttura con il codice dell'applicazione e debba mantenere la compatibilità con API e ABI a ritroso. Prova a farlo controllando la dimensione della struttura passata ad esso.In che modo sizeof (struct) aiuta a fornire la compatibilità ABI?
Supponiamo che la seguente struttura debba essere aggiornata. Nella versione della libreria 1,
typedef struct {
int size;
char* x;
int y;
} foo;
Nella versione 2 della libreria, viene aggiornato a:
typedef struct {
int size;
char* x;
int y;
int z;
} foo_2;
Ora, biblioteca versione 2 vuole verificare se l'applicazione sta passando il nuovo foo_2
o il vecchio foo
come argomento, arg
, a una funzione. Si presuppone che l'applicazione ha impostato arg.size
-sizeof(foo)
o sizeof(foo_2)
e cerca di capire se il codice dell'applicazione groks versione 2.
if(arg.size == sizeof(foo_2)) {
// The application groks version 2 of the library. So, arg.z is valid.
} else {
// The application uses of version 1 of the library. arg.z is not valid.
}
mi chiedo il motivo per cui questo non mancherà. Su GCC 4.6.3, con flag -O3, sia sizeof(foo)
sia sizeof(foo_2)
sono 24. Quindi, il codice libreria v2 non riuscirà a capire se l'applicazione sta passando una struttura di tipo foo
o foo_2
? Se sì, come mai questo approccio sembra essere stato usato?
http://blogs.msdn.com/b/oldnewthing/archive/2003/12/12/56061.aspx
seguire su domanda: C'è una buona ragione per favorire l'utilizzo di sizeof(struct)
di discriminazione versione? Come indicato nei commenti, perché non utilizzare un membro esplicito version
nella struttura condivisa?
Da dove vieni a 24? –
Probabilmente non funzionerà. 'sizeof' è una cosa in fase di compilazione e si desidera controllare la dimensione in * runtime *. –
@BasileStarynkevitch: Hm, cosa? Sappiamo quale versione della struttura utilizzata dal chiamante, non il callee, quindi sembra buona da quella direzione. Tuttavia, spiky ha ragione che sulla maggior parte delle piattaforme a 64 bit, il puntatore è allineato e dimensionato a 8 byte, l'int 4, e quindi non vi è alcuna differenza di dimensione tra le due strutture. – Deduplicator