Penso che nascondere la definizione della struttura renda il codice più sicuro mentre si applica con l'aiuto del compilatore che nessun membro della struttura può accedere direttamente. Lo svantaggio è che gli utenti non possono dichiarare le variabili del tipo di struttura sullo stack perché la dimensione della struttura non è nota, mentre a volte è preferibile evitare di utilizzare malloc()
. Questo può essere (con un parziale successo) risolto con alloca(3)
che è presente in tutte le principali implementazioni di libc, sebbene questa funzione non sia conforme a POSIX. Considerati questi piccoli vantaggi e svantaggi, un tale design può essere considerato generalmente buono?È buona norma nascondere la definizione della struttura in C?
In lib.h
:
struct foo;
extern size_t foo_size;
int foo_get_bar (struct foo *);
In lib.c
:
struct foo {
int bar;
};
size_t foo_size = sizeof foo;
int foo_get_bar (struct foo *foo)
{
return foo->bar;
}
In example.c
:
#include "lib.h"
int bar(void) {
struct foo *foo = alloca (foo_size);
foo_init (foo);
return foo_get_bar (foo);
}
UPD: Aggiornamento della questione, affermando esplicitamente che l'idea di usare alloca()
deve essere in grado di dichiarare la struttura sullo stack nascondendo la sua definizione.
La scelta più comune è usare qualcosa come 'foo_create' e' foo_destroy', il che significa che non esporre * nessun * dettaglio della tua struttura, e che può fare cose più avanzate come la memorizzazione internamente di 'malloc''d puntatori . Esistono poche e preziose situazioni in cui * in realtà * si desidera utilizzare 'alloca', a parte forse i sistemi incorporati in cui' malloc' e gli amici sono super-limitati. –
Se la struttura è opaca, sarebbe un cattivo progetto avere codice client che ha bisogno di allocare o dichiarare qualsiasi variabile di quel tipo come mostrato nell'esempio. Tutte le istanze della struttura dovrebbero provenire dalla libreria stessa. – kaylum
'VLA []' consentito? (C99)? Dichiarare un array di caratteri di 'foo_size' (usando' alignas') può funzionare. Eppure, in gerneral, sono d'accordo con @kaylum – chux