Warum typedefs für Strukturen verwenden?

12

In C (ANSI, C99 usw.) leben Strukturen in ihrem eigenen Namespace. Eine Struktur für eine verknüpfte Liste könnte ungefähr so ​​aussehen:

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

Für die meisten C-Programmierer erscheint es jedoch ganz natürlich, diese Strukturen wie die folgenden automatisch zu definieren

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

Und dann referenzieren Sie die Struktur wie ein normaler Typ, dh get_next_element(my_buffer_type * ptr).

Jetzt ist meine Frage: Gibt es einen bestimmten Grund dafür?

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

Some people are opposed to the extensive use of typedefs. Most arguments center on the idea that typedefs simply hide the actual data type of a variable. For example, Greg Kroah-Hartman, a Linux kernel hacker and documenter, discourages their use for anything except function prototype declarations. He argues that this practice not only unnecessarily obfuscates code, it can also cause programmers to accidentally misuse large structures thinking them to be simple types.[4]

Andere argumentieren, dass die Verwendung von typedefs die Pflege von Code erleichtern kann. K & R gibt an, dass es zwei Gründe für die Verwendung eines typedef gibt. Erstens bietet es eine Möglichkeit, ein Programm portabler zu machen. Anstatt einen Typ überall in den Quelldateien des Programms ändern zu müssen, muss nur eine einzige typedef-Anweisung geändert werden. Zweitens kann ein typedef das Verständnis einer komplexen Deklaration erleichtern.

Ich persönlich frage mich, ob es nicht genug Vorteile gibt, einen separaten structNamespace zu haben, um manchmal keine typedef'd Strukturen zu verwenden, und da es mehrere C-Programmierkulturen gibt (Windows C-Programmierung hat meiner Erfahrung nach andere Traditionen als Linux C-Programmierung), wenn es andere gibt Traditionen, die mir nicht bekannt sind.

Dann interessieren mich historische Überlegungen (Vorgänger, erste Versionen von C).

wirrbel
quelle
4
Der Zweck von a typedef besteht darin, den tatsächlichen Typ einer Variablen auszublenden. Nehmen Sie time_tals Beispiel: Wenn Benutzer den zugrunde liegenden Integer-Typ verwenden, wird eine Änderung in der Implementierung, wie sie 2038 erforderlich sein wird, eine Menge Code beschädigen. Wenn Leute Strukturen verwenden, ohne zu verstehen warum, ist dies ein Fehler im Programmierer, nicht im Konstrukt.
Blrfl

Antworten:

14

Ich habe an einem großen Projekt gearbeitet, bei dem häufig typedef'd Strukturen verwendet wurden. Wir haben dies aus mehreren Gründen getan. Bitte beachten Sie, dass dies eine Trennung vor C99 und Namespaces war.

  1. Es war einfacher zu tippen my_buffer_type *bufferstatt struct tag_buffer_type *buffer, und für die Größe der Codebasis (1 M + loc) , die einen großen Unterschied gemacht.

  2. Es abstrahiert die Struktur in ein Objekt. Anstatt uns auf jede einzelne Variable innerhalb der Struktur zu konzentrieren, würden wir uns auf das Datenobjekt konzentrieren, das sie darstellt. Diese Abstraktion führte zu allgemein nützlicherem und einfacher zu schreibendem Code.

    • Ich denke, dies steht in direktem Widerspruch zu dem Zitat, das Sie Greg Kroah-Hartman zugeschrieben haben. FWIW, dieses Projekt war eine Client / Server-Anwendung und kein Kernel, daher sind definitiv einige andere Überlegungen zu berücksichtigen.
  3. Durch die Behandlung der Struktur als Objekt konnten wir die Informationen auch besser einkapseln. Bei der Codeüberprüfung gab es einige Situationen, in denen ein neuerer Entwickler gegen die von uns eingeführten Kapselungsprinzipien verstieß. Die Verwendung typedef'd Strukturen machte diese Verstöße wirklich offensichtlich.

  4. Die Portabilität war ein Problem, da wir für ein halbes Dutzend Plattformen mit dem Server und einige weitere mit dem Client geschrieben haben.


quelle
5

Jedes Mal anstatt zu tippen

struct my_buffer_type *buffer;

wenn Sie typedefes können Sie direkt verwenden

my_buffer_type *buffer;

typedefDie Hauptanwendung besteht darin, die Anzahl der zum Schreiben von Code erforderlichen Tastenanschläge zu verringern und die Lesbarkeit zu verbessern.

AMohan
quelle
Sie haben Recht, aber ich habe diese Tatsache bereits in meiner Frage beschrieben.
Wirrbel