Зачем использовать 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 просто скрывают фактический тип данных переменной. Например, Грег Кроа-Хартман (Greg Kroah-Hartman), хакер и документалист по ядру Linux, не рекомендует их использовать для чего-либо, кроме объявлений прототипов функций. Он утверждает, что эта практика не только излишне запутывает код, но также может заставить программистов случайно неправильно использовать большие структуры, считая их простыми типами. [4]

Другие утверждают, что использование typedefs может облегчить поддержку кода. K & R утверждает, что есть две причины для использования typedef. Во-первых, это дает возможность сделать программу более переносимой. Вместо того, чтобы менять тип везде, где он появляется в исходных файлах программы, нужно изменить только один оператор typedef. Во-вторых, typedef может облегчить понимание сложной декларации.

Я лично задаюсь вопросом: structнеужели нет достаточного преимущества наличия отдельного пространства имен, чтобы иногда не использовать структуры typedef'd, и поскольку существует несколько культур программирования C (в моем опыте программирование на Windows C отличается от традиций Linux C), если есть другие традиции, о которых я не знаю.

Тогда меня интересуют исторические соображения (предшественники, первые версии C).


4
Цель a typedef - скрыть фактический тип переменной. Возьмите time_tв качестве примера: если люди будут использовать базовый целочисленный тип, то такое изменение в реализации, которое потребовалось в 2038 году, сломает очень много кода. «Если люди используют структуры, не понимая, почему, это ошибка программиста, а не конструкции.
Blrfl

Ответы:


14

Я работал над большим проектом, который широко использовал структуры typedef'd. Мы сделали это по нескольким причинам. Пожалуйста, имейте в виду, что это было до C99 и сегрегация пространства имен.

  1. Было проще печатать my_buffer_type *bufferвместо struct tag_buffer_type *buffer, а для размера кодовой базы (1M + loc) это имело большое значение.

  2. Он абстрагирует структуру в объект. Вместо того, чтобы фокусироваться на каждой отдельной переменной в структуре, мы бы сфокусировались на объекте данных, который она представляла. Эта абстракция привела в целом к ​​более полезному и легкому написанию кода.

    • Я думаю, что это прямо противоречит приведенной вами цитате Грега Кроа-Хартмана. FWIW, этот проект был клиент-серверным приложением, а не ядром, так что, безусловно, следует принимать во внимание некоторые другие соображения.
  3. Обработка структуры как объекта также позволила нам лучше инкапсулировать информацию. При проверке кода было довольно много ситуаций, когда новый разработчик нарушал принципы инкапсуляции, которые мы внедрили. Использование структур typedef действительно сделало эти нарушения очевидными.

  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.