Навіщо використовувати typedefs для структур?


12

в C (ANSI, C99 та ін.) структури живуть у власному просторі імен. Структура для пов'язаного списку може виглядати приблизно так:

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

Однак, здається, цілком природно, що для більшості програмістів на C автоматично вводити такі структури, як нижче

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

А потім посилайтесь на структуру як на звичайний тип, тобто get_next_element(my_buffer_type * ptr).

Тепер моє запитання: чи є конкретна причина цього?

У Вікіпедії йдеться про http://en.wikipedia.org/wiki/Typedef#Usage_concerns

Деякі люди проти широкого використання typedefs. Більшість аргументів зосереджені на ідеї, що typedefs просто приховує фактичний тип даних змінної. Наприклад, Грег Кроа-Хартман, хакер ядра Linux та документатор, відмовляє їх у використанні для будь-якого, крім декларацій прототипу функцій. Він стверджує, що така практика не тільки необгрунтовано обтяжує код, але також може спричинити програмістів випадково неправомірного використання великих структур, вважаючи їх простими типами. [4]

Інші стверджують, що використання typedefs може полегшити підтримку коду. K&R заявляє, що існують дві причини використання typedef. По-перше, він забезпечує засіб зробити програму більш портативною. Замість того, щоб змінювати тип скрізь, де він відображається у всіх вихідних файлах програми, потрібно змінити лише одну заяву typedef. По-друге, typedef може полегшити розуміння складної заяви.

Мені особисто цікаво, чи не існує достатньої користі від того, щоб мати окремий structпростір імен, щоб іноді не використовувати структури typedef'd, і оскільки існує декілька культур програмування С (навколо мого досвіду програмування Windows C має інші традиції, ніж програмування Linux C) традиції, які я не знаю.

Тоді мене цікавлять історичні міркування (попередники, перші версії С).


4
Мета a typedef - приховати фактичний тип змінної. Візьмемо time_tдля прикладу: якщо люди перейдуть, використовуючи основний цілий тип, зміна в реалізації такої, яка буде потрібна в 2038 році, порушить дуже багато коду. FЯкщо люди використовують структури, не розуміючи, чому, це невдача програміста, а не конструкції.
Blrfl

Відповіді:


14

Я працював над великим проектом, який широко використовував структури typedef'd. Ми зробили це з кількох причин. Будь ласка, майте на увазі, що це було розділенням до C99 та простору імен.

  1. Було легше вводити my_buffer_type *bufferзамість struct tag_buffer_type *buffer, а також для розміру кодової бази (1M + loc), яка мала велику різницю.

  2. Це абстрагує структуру на об'єкт. Замість того, щоб зосередитись на кожній окремій змінній у структурі, ми орієнтувались би на об'єкт даних, який вона представляла. Ця абстракція призвела до загального кориснішого та простішого написання коду.

    • Я думаю, що це прямо суперечить цитаті Грега Круа-Хартмана, яку ви надали. FWIW, цей проект був програмою клієнт / сервер, а не ядром, тому обов'язково слід враховувати деякі різні міркування.
  3. Трактування структури як об'єкта також дозволило нам краще капсулювати інформацію. Перегляд коду виявив досить багато ситуацій, коли новіший розробник порушив би принципи інкапсуляції, які ми застосовували. Використання структур typedef'd дійсно зробило ці порушення очевидними.

  4. Переносність викликала занепокоєння, оскільки ми писали про півтора десятка платформ із сервером та ще декілька з клієнтом.


5

Кожен раз замість набору тексту

struct my_buffer_type *buffer;

якщо ви typedefце, ви можете безпосередньо використовувати

my_buffer_type *buffer;

typedefОсновне використання - зменшити кількість натискань клавіш, необхідних для написання коду, та підвищити читабельність.


ви праві, але я вже описав цей факт у своєму питанні.
wirrbel
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.