Требуется ли typedef в C?

Typedef очень полезен для переносимых имен, имен тегов ( typedef struct foo Foo; ) и сохранения усложненных (функций) деклараций читаемых ( typedef int (*cmpfunc)(const void *, const void *); ).

Но существуют ли ситуации в C, где действительно требуется typedef? Там, где вы не можете сделать то же самое, просто выписывая производный тип.

Чтобы немного уточнить: я имею в виду для пользователей языков, а не для разработчиков. Весь stdint.h – хороший пример второй категории.

Заключение

Спасибо за все Ваши ответы. Я думаю, что могу подвести итог:

  • Библиотеке C99 требуется typedef для реализации различных (u)intN_t типов (u)intN_t .
  • На C89 вы действительно хотите сами использовать typedefs для создания подобных переносных типов.
  • Вам может понадобиться typedef при использовании макроса va_arg , но я сомневаюсь, что вы на практике столкнетесь с этими производными типами.

typedef по определению является псевдонимом. Таким образом, вы всегда можете заменить псевдоним фактическим типом. Это не было бы алиасом иначе.

Это не значит, что избегать typedef было бы хорошей идеей.

Спасибо всем за ваши ответы. Я посмотрел еще немного и нашел это в C99, J.2 Неопределенное поведение:

Поведение не определено в следующих случаях: […]

  • Параметр типа для макроса va_arg не таков, что указатель на объект такого типа может быть получен просто путем постфиксации a * (7.15.1.1).

Поэтому, когда вы хотите передать / извлечь сложные производные типы в va_arg такие как int (*)[] вам нужно ввести этот тип в нечто такое, для чего это возможно (обновлено / исправлено):

 typedef int (*intarrptr)[4]; intarrptr x = va_arg(ap, intarrptr); 

Поскольку это трудно найти и действительно полезно для этого, можно сделать вывод, что это не сильный аргумент в пользу необходимости typedef .

Из Википедии:

typedef – это ключевое слово на языках программирования C и C ++. objective typedef – назначить альтернативные имена существующим типам, чаще всего те, чье стандартное объявление громоздко, потенциально запутывает или может варьироваться от одной реализации к другой. 1

Основываясь на этом определении, это никогда не требуется, поскольку вы всегда можете просто выписать расширенную форму. Однако могут быть макроопределения, которые выбирают typedef для использования на платформе или что-то еще. Поэтому всегда использование расширенной формы может быть не очень переносимым.

это определенно требуется, хорошим примером является size_t, который typedef’d на разных платформах.

Ключевое слово typedef, безусловно, необходимо в наборах тестов, которые проверяют компилятор C для соответствия ISO-C.

В коде, который явно не предполагается использовать typedef (например, тестовый набор выше), он часто очень полезен, но не имеет существенного значения, поскольку он устанавливает только псевдоним другого типа. Он не создает тип.

Наконец, я не буду считать такие вещи, как избегать ограничения на компилятор на предварительно обработанном исходном файле с помощью аббревиатуры typedefs.

Да. Целые типы, которые должны быть фиксированного размера. например int32_t (и вы хотите, чтобы ваш код имел шанс сражаться за int32_t ).

Макрос offsetof () требует имени struct и membername и поэтому не может использоваться с определениями встроенных структур. Ну, может быть, на вашей реализации это возможно, но это не гарантируется стандартом C.

Обновление: Как указано в комментариях, это возможно:

 struct blah { int a; int b; }; x = offsetof(struct blah, a); // legal 

Но определение структуры не является:

 x = offsetof(struct {int a; int b;}, a); // illegal 

Первый не содержит ключевое слово typedef , но невозможно также установить определение структуры. Какая версия указана в «простой записи производного типа», неясно.

Нет.

Typedef не создает абсолютно новый тип, как говорят class на C ++, он просто создает псевдоним типа – один идентификатор для чего-то еще, что уже существует. В typedef вы не определяете никакого нового поведения, семантики, конверсий или операторов.

Нет. Я думаю, что я в безопасности, говоря это!

Я не знаю случаев, когда typedef явно требуется в C.

не «чрезвычайно полезно»?

мне даже не сложно думать о проекте со struct для каждого члена структуры, указателя, аргументации и т. д.

Для меня typedef обеспечивает абстракцию. Он сохраняет мой код в чистоте и очень легко понять. Вы можете жить без typedef так же, как вы можете жить без всех языков высокого уровня и придерживаться сборки или машинного языка.

Отдельные программисты не обязаны создавать свои собственные typedef. Нет универсального правила, говорящего, что я не могу писать такие вещи, как

 int *(*(*x())[5])(); 

если я так желаю (хотя стандарты кодирования моей компании могут нахмуриться).

Тем не менее, они находятся по всей стандартной библиотеке ( FILE , size_t и т. Д.), Поэтому вы действительно не можете избежать использования имен typedef.

Мы используем typedef для работы, сохраняя независимость кодовой платформы. Например, мы делаем что-то вроде

 typedef unsigned char SHORT; 

это делает код более удобочитаемым и легко переносимым.

Без typedef вам нужно использовать ключевое слово struct everytime, если вы используете struct в объявлениях. С typedef вы можете опустить это.

 struct Person { char * name; }; struct Person p; /* need this here*/ typedef struct _Person { char * name; } Person; Person p; /* with typedef I can omit struct keyword here */