Estructuras C opacas: ¿cómo deben declararse?
He visto los dos estilos siguientes de declarar tipos opacos en las API de C. ¿Hay alguna ventaja clara al usar un estilo sobre el otro?
Opción 1
// foo.h
typedef struct foo * fooRef;
void doStuff(fooRef f);
// foo.c
struct foo {
int x;
int y;
};
Opción 2
// foo.h
typedef struct _foo foo;
void doStuff(foo *f);
// foo.c
struct _foo {
int x;
int y;
};
2 answers
Mi voto es por la tercera opción que mouviciel publicó y luego eliminó:
He visto una tercera vía:
// foo.h struct foo; void doStuff(struct foo *f); // foo.c struct foo { int x; int y; };
Si realmente no puedes soportar escribir la palabra clave struct
, typedef struct foo foo;
(nota: deshazte del subrayado inútil y problemático) es aceptable. Pero hagas lo que hagas, nunca use typedef
para definir nombres para tipos de puntero. Oculta la información extremadamente importante de que las variables de este tipo hacen referencia a un objeto que podría modificarse cada vez que pasarlos a las funciones, y hace que lidiar con versiones del puntero calificadas de manera diferente (por ejemplo, const
calificadas) sea un dolor mayor.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-19 04:23:05
bar(const fooRef)
declara una dirección inmutable como argumento. bar(const foo *)
declara una dirección de un foo inmutable como argumento.
Por esta razón, tiendo a preferir la opción 2. Es decir, el tipo de interfaz presentado es uno donde cv-ness se puede especificar en cada nivel de indirección. Por supuesto, uno puede eludir la opción 1 library writer y simplemente usar foo
, abriéndose a todo tipo de horror cuando el library writer cambia la implementación. (Es decir, el escritor de la biblioteca de la opción 1 solamente percibe que fooRef
es parte de la interfaz invariante y que foo
puede venir, ir, alterarse, lo que sea. El escritor de la biblioteca de opción 2 percibe que foo
es parte de la interfaz invariante.)
Me sorprende más que nadie haya sugerido construcciones combinadas typedef/struct.typedef struct { ... } foo;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-06 18:30:55