Что представляет собой тип, за которым следует t (подчеркивание-t)?

Это кажется простым вопросом, но я не могу найти его с помощью поиска переполнения стека или Google. Что делает тип, за которым следует _t в смысле? Такие как

int_t anInt;

Я вижу это много в коде C, предназначенном для работы с оборудованием-я не могу не думать, что они связаны.

10 ответов


как отметил Дуглас Майл, он в основном обозначает имя типа. Следовательно, вам не рекомендуется заканчивать имена переменных или функций с помощью'_t' Так как это может вызвать некоторую путаницу. А также size_t, стандарт C89 определяет wchar_t, off_t, ptrdiff_t, и, возможно, некоторые другие, которые я забыл. Стандарт C99 определяет множество дополнительных типов, таких как uintptr_t, intmax_t, int8_t, uint_least16_t, uint_fast32_t и так далее. Эти новые типы формально определены в <stdint.h> но чаще всего вы будете использовать <inttypes.h> который (необычно для стандартных заголовков C) включает <stdint.h>. Это (<inttypes.h>) также определяет макросы для использования с printf() и scanf().

как отметил Мэтт Кертис, в суффиксе нет значения для компилятора; это ориентированное на человека соглашение.

однако, вы также должны отметить, что POSIX определяет много дополнительных имен типов, заканчивающихся на'_t и резервы суффикс для реализации. Это означает, что если вы работаете над системами, связанными с POSIX, определение собственных имен типов с соглашением не рекомендуется. Система, над которой я работаю, сделала это (более 20 лет); мы регулярно сталкиваемся с системами, определяющими типы с тем же именем, что и мы.


это соглашение, используемое для именования типов данных, e.g с typedef:


typedef struct {
  char* model;
  int year;
...
} car_t;


на _t обычно обертывает непрозрачное определение типа.

GCC просто добавить имена, которые заканчиваются на _t в зарезервированное пространство имен, которое вы не можете использовать, чтобы избежать конфликтов с будущими версиями Standard C и POSIX (руководство библиотеки GNU C). После некоторых исследований я, наконец, нашел правильную ссылку внутри стандарта POSIX (1003.1, обоснование (информативное)):

B. 2.12 Типов Данных

требование дополнительные типы, определенные в этом разделе, в ‘ІТ’ была продиктована проблема загрязнения космического пространства. Трудно определить тип (где этот тип не является одним определяется IEEE Std 1003.1-2001) в одном заголовочном файле и использовать его в другом без добавления символов к пространству имен программы. Чтобы позволить разработчикам представить свои собственные типы, все соответствуя применения необходимы, что во избежание символы заканчивая в "_t", которое позволяет реализатор для предоставления дополнительных типы. Поскольку основное использование типов находится в определении элементы структуры, которые могут (и во многих случаях должны) быть добавлены в структуры, определенные в IEEE Std 1003.1-2001, потребность в дополнительных типах является убедительной.

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

например, ваша программа соответствует POSIX 1003.1 Вопросы 6 и вы определили тип foo_t. POSIX 1003.1 выпуски 7 в конечном итоге выпущен с новым определенным типом foo_t. Ваша программа не соответствует новой версии, что может быть проблемой. Ограничение _t использование предотвращает рефакторинг кода. Таким образом, если вы нацелены на соответствие POSIX, вам определенно следует избегать _t Как говорится в стандарте.

Примечание: лично я стараюсь придерживаться POSIX, потому что я думаю, что это дает хорошее основы чистого программирования. Более того, я очень люблю стиль кодирования Linux (Глава 5) руководство. Есть несколько веских причин, почему не использовать typedef. Надеюсь, это поможет!


Это стандартное соглашение об именах для типов данных, обычно определяемых typedefs. Многие c-коды, связанные с аппаратными регистрами, используют стандартные имена C99 для подписанных и неподписанных типов данных фиксированного размера. Как соглашение, эти имена находятся в стандартном файле заголовка (stdint.h), и заканчиваются на _t.


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

вы можете быть более знакомы с общими практиками C для именования переменных... Это похоже на то, как обычно вставлять p спереди для указателя и использовать подчеркивание перед глобальными переменными (это немного менее распространено) и использовать имена переменных i, j и k для временного цикла переменная.

в коде, где важен размер и порядок слов, очень часто используются пользовательские определенные типы, которые являются явными, такие как BYTE WORD (обычно 16 бит) DWORD (32-бит).

int_t не так хорошо, потому что определение int варьируется между платформами -- так чей int вы соответствуете? (Хотя в наши дни большинство PC-ориентированных разработок рассматривает его как 32 бита, многие вещи для разработки без ПК по-прежнему рассматривают int как 16 бит).


Это означает тип. size_t тип размер.


Это просто соглашение, которое означает "тип". Это ничего не значит для компилятора.


было несколько хороших объяснений по этому вопросу. Просто чтобы добавить еще одну причину для повторного определения типов:

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

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

пример:

typedef unsigned long dc_uint32_t;

Если вы имеете дело с кодом аппаратного интерфейса, автор кода, на который вы смотрите, мог бы определить int_t быть целым числом определенного размера. Стандарт C не присваивает определенный размер int type (это зависит от вашего компилятора и целевой платформы, потенциально), и с использованием определенного int_t type позволит избежать этой проблемы переносимости.

Это особенно важное соображение для кода интерфейса оборудования, который может быть почему вы сперва замечали там съезд.


например, в C99, /usr / include / stdint.h:

typedef unsigned char           uint8_t;
typedef unsigned short int      uint16_t;
#ifndef __uint32_t_defined
typedef unsigned int            uint32_t;
# define __uint32_t_defined
#endif
#if __WORDSIZE == 64
typedef unsigned long int       uint64_t;
#else
__extension__
typedef unsigned long long int  uint64_t;
#endif

_t всегда означает, определенный typedef.