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

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

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

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

Заключение

Спасибо за весь ваш вклад. Думаю, я могу обобщить его как:

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

Ответ 1

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

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

Ответ 2

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

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

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

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

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

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

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

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

Ответ 7

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

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

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

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

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

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

Ответ 8

Нет.

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

Ответ 9

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

Ответ 10

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

Ответ 11

не является "чрезвычайно полезным", как требовалось?

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

Ответ 12

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

Ответ 13

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

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

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

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

Ответ 14

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

typedef unsigned char SHORT;

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

Ответ 15

Без 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 */