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

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

13 голосов
/ 30 сентября 2010

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, но я сомневаюсь, что вы встретите эти производные типы на практике.

Ответы [ 15 ]

15 голосов
/ 30 сентября 2010

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

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

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

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

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

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

14 голосов
/ 30 сентября 2010

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

Это не значит, что избегать typedef было бы неплохо.

5 голосов
/ 30 сентября 2010

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

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

2 голосов
/ 30 сентября 2010

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

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

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

2 голосов
/ 30 сентября 2010

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

1 голос
/ 30 сентября 2010

No.

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

1 голос
/ 30 сентября 2010

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

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

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

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

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

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

1 голос
/ 30 сентября 2010

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

0 голосов
/ 30 сентября 2010

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

typedef unsigned char SHORT;

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

0 голосов
/ 30 сентября 2010

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

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

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

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

...