Что представляет собой тип, за которым следует _t (underscore-t)? - PullRequest
226 голосов
/ 24 октября 2008

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

int_t anInt;

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

Ответы [ 10 ]

181 голосов
/ 24 октября 2008

Как отметил Дуглас Мейл, это в основном обозначает имя типа. Следовательно, вам не рекомендуется заканчивать имена переменных или функций символом '_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 лет); мы регулярно сталкиваемся с системами, определяющими типы с тем же именем, что и мы.

42 голосов
/ 24 октября 2008

Это соглашение, используемое для именования типов данных, например, с typedef:


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

32 голосов
/ 04 октября 2012

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

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

B.2.12 Типы данных

Требование, чтобы дополнительные типы, определенные в этом разделе, заканчивались на in ‘t, было вызвано проблема загрязнения пространства имен. Трудно определить тип (где этот тип не один определено стандартом 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 Coding Style (глава 5) . Есть несколько веских причин, почему не использовать typedef. Надеюсь, что это поможет!

17 голосов
/ 24 октября 2008

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

11 голосов
/ 24 октября 2008

_t по сути не имеет никакого особого значения. Но это стало обычным делом для добавления суффикса _t к typedef.

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

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

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

10 голосов
/ 24 октября 2008

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

9 голосов
/ 24 октября 2008

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

8 голосов
/ 24 октября 2008

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

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

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

Пример:

typedef unsigned long dc_uint32_t;
7 голосов
/ 24 октября 2008

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

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

0 голосов
/ 11 июля 2018

Например, в 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...