¿Por qué usar typedefs para estructuras?

12

en C (ANSI, C99, etc.), las estructuras viven en su propio espacio de nombres. Una estructura para una lista vinculada podría verse así:

struct my_buffer_type {
   struct my_buffer_type * next;
   struct my_buffer_type * prev;
   void * data;
};

Sin embargo, parece bastante natural que la mayoría de los programadores de C tipifiquen automáticamente esas estructuras como las siguientes

typedef struct tag_buffer_type {
   struct tag_buffer_type * next;
   struct tag_buffer_type * prev;
   void * data;
} my_buffer_type;

Y luego haga referencia a la estructura como un tipo normal, es decir get_next_element(my_buffer_type * ptr).

Ahora mi pregunta es: ¿Hay una razón específica para esto?

Wikipedia dice http://en.wikipedia.org/wiki/Typedef#Usage_concerns

Algunas personas se oponen al uso extensivo de typedefs. La mayoría de los argumentos se centran en la idea de que typedefs simplemente oculta el tipo de datos real de una variable. Por ejemplo, Greg Kroah-Hartman, un hacker y documentador del kernel de Linux, desaconseja su uso para cualquier cosa, excepto las declaraciones de prototipos de funciones. Argumenta que esta práctica no solo ofusca innecesariamente el código, sino que también puede hacer que los programadores usen accidentalmente grandes estructuras pensando que son tipos simples. [4]

Otros sostienen que el uso de typedefs puede hacer que el código sea más fácil de mantener. K&R afirma que hay dos razones para usar un typedef. Primero, proporciona un medio para hacer que un programa sea más portátil. En lugar de tener que cambiar un tipo en todas partes que aparece en los archivos fuente del programa, solo se necesita cambiar una sola declaración typedef. Segundo, un typedef puede hacer que una declaración compleja sea más fácil de entender.

Personalmente, me pregunto si no hay suficiente beneficio de tener el structespacio de nombres separado para no usar estructuras typedef'd y, dado que hay varias culturas de programación en C (la programación de Windows C tiene tradiciones diferentes a la programación de Linux C en mi experiencia) si hay otras tradiciones que no conozco.

Entonces me interesan las consideraciones históricas (predecesoras, primeras versiones de C).

wirrbel
fuente
44
El propósito de a typedef es ocultar el tipo real de una variable. Tomemos time_tcomo ejemplo: si las personas usan el tipo entero subyacente, un cambio en la implementación, como el que se requerirá en 2038, romperá una gran cantidad de código. Si las personas usan estructuras sin entender por qué, eso es un fracaso en el programador, no en la construcción.
Blrfl

Respuestas:

14

Trabajé en un gran proyecto que utilizaba ampliamente estructuras typedef'd. Lo hicimos por un par de razones. Tenga en cuenta que esto fue anterior a C99 y la segregación de espacio de nombres.

  1. Era más fácil escribir en my_buffer_type *bufferlugar de struct tag_buffer_type *buffer, y para el tamaño de la base de código (1M + loc) eso hizo una gran diferencia.

  2. Resume la estructura en un objeto. En lugar de enfocarnos en cada variable individual dentro de la estructura, nos enfocaríamos en el objeto de datos que representaba. Esta abstracción condujo a un código generalmente más útil y más fácil de escribir.

    • Creo que esto está en contradicción directa con la cita atribuida a Greg Kroah-Hartman que usted proporcionó. FWIW, ese proyecto fue una aplicación cliente / servidor y no un núcleo, por lo que definitivamente hay algunas consideraciones diferentes a tener en cuenta.
  3. Tratar la estructura como un objeto también nos permitió encapsular mejor la información. La revisión de código detectó algunas situaciones en las que un desarrollador más nuevo violaría los principios de encapsulación que habíamos implementado. El uso de estructuras typedef'd realmente hizo que esas violaciones fueran obvias.

  4. La portabilidad era una preocupación ya que escribimos para media docena de plataformas con el servidor y bastantes más con el cliente.


fuente
5

Cada vez en lugar de escribir

struct my_buffer_type *buffer;

si typedeflo puedes usar directamente

my_buffer_type *buffer;

typedefEl uso principal es reducir la cantidad de pulsaciones de teclas necesarias para escribir código y mejorar la legibilidad.

AMohan
fuente
tienes razón, pero ya he descrito este hecho en mi pregunta.
wirrbel