¿Qué representa un tipo seguido de _t (subrayado-t)?


261

Esta parece una pregunta simple, pero no puedo encontrarla con la búsqueda de Stack Overflow o Google. ¿Qué significa un tipo seguido de un _tmedio? Como

int_t anInt;

Lo veo mucho en el código C destinado a tratar estrechamente con el hardware; no puedo evitar pensar que están relacionados.


3
¿Dónde se int_tdefine? Si siempre se define como int, no es útil; es mucho más claro usarlo intdirectamente. Si no siempre se define como int(por ejemplo, si podría ser long into short int), entonces es un nombre mal elegido y confuso.
Keith Thompson

Respuestas:


213

Como señaló Douglas Mayle, básicamente denota un nombre de tipo. En consecuencia, sería desaconsejable terminar los nombres de variables o funciones con '_t ' ya que podría causar cierta confusión. Así como size_t, las norma define C89 wchar_t, off_t, ptrdiff_t, y probablemente algunos otros que he olvidado. El estándar C99 define un montón de tipos adicionales, tales como uintptr_t, intmax_t, int8_t, uint_least16_t, uint_fast32_t, y así sucesivamente. Estos nuevos tipos se definen formalmente, <stdint.h>pero la mayoría de las veces se usará lo <inttypes.h>que (inusualmente para los encabezados C estándar) incluye <stdint.h>. También ( <inttypes.h>) define macros para usar con printf()y scanf().

Como señaló Matt Curtis, no hay significado para el compilador en el sufijo; Es una convención orientada al ser humano.

Sin embargo, también debe tener en cuenta que POSIX define muchos nombres de tipos adicionales que terminan en ' _t' y reserva el sufijo para la implementación. Eso significa que si está trabajando en sistemas relacionados con POSIX, no es aconsejable definir sus propios nombres de tipo con la convención. El sistema en el que trabajo lo ha hecho (durante más de 20 años); regularmente nos tropezamos con sistemas que definen tipos con el mismo nombre que nosotros definimos.


44
parece razonable que el sistema operativo y las bibliotecas de tiempo de ejecución comunes definan tipos con nombres genéricos; pero, ¿no deberían los tipos de su empresa también anteponerse con un prefijo o algo así?
Toybuilder

17
Utilizo _type en lugar de _t en mis typedefs precisamente para evitar eso.
CesarB

44
@ Jonathan Leffler: ¿Qué convención de nomenclatura usarías para los tipos definidos por el usuario?
J. Andrew Laughlin

15
@Andrew: si tiene una abreviatura conveniente para usar como prefijo, entonces puede estar seguro de usar abbr_xxxxx_tnombres de tipo. Sin dicho prefijo, puede quedar atrapado en cualquier momento. En general, los _ttipos estandarizados usan todas las minúsculas ( FILEy DIRson dos excepciones, dos veces: todas mayúsculas y no mayúsculas _t), por lo que puede usar CamelCase_tcon seguridad moderada, con o sin las mayúsculas principales. El sistema en el que trabajo principalmente tiende a vivir peligrosamente y se usa de _ttodos modos, pero en ocasiones nos ha mordido. Tiendo a usar CamelCasesin sufijo para mi propio trabajo; mis funciones suelen ser todas minúsculas.
Jonathan Leffler

55
@ JonathanLeffler, comencé a usar esa convención, CamelCase para tipos, lower_case para funciones. Busqué esta pregunta con la esperanza de no ser el único. Gracias por la validación!
Austin Mullins

50

Es una convención utilizada para nombrar tipos de datos, por ejemplo, con typedef:


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


43

Por lo _tgeneral, envuelve una definición de tipo opaco.

GCC simplemente agrega nombres que terminan _ten el espacio de nombres reservado que no puede usar, para evitar conflictos con versiones futuras de Standard C y POSIX (manual de la biblioteca GNU C) . Después de un poco de investigación, finalmente encontré la referencia correcta dentro del Estándar POSIX (1003.1, Justificación (Informativo)):

B.2.12 Tipos de datos

El requisito de que los tipos adicionales definidos en esta sección terminen en '' _t '' fue provocado por el problema de la contaminación del espacio de nombres. Es difícil definir un tipo (donde ese tipo no es uno definido por IEEE Std 1003.1-2001) en un archivo de encabezado y usarlo en otro sin agregar símbolos al espacio de nombre del programa. Para permitir que los implementadores proporcionen sus propios tipos, todas las aplicaciones conformes deben evitar que los símbolos terminen en '' _t '', lo que permite que el implementador proporcione tipos adicionales. Debido a que el uso principal de los tipos está en la definición de los miembros de la estructura, que pueden (y en muchos casos deben) agregarse a las estructuras definidas en IEEE Std 1003.1-2001, la necesidad de tipos adicionales es convincente.

En pocas palabras, el Estándar dice que hay buenas posibilidades de extender la lista de tipos del Estándar, por lo tanto, el Estándar restringe el _tespacio de nombres para su propio uso.

Por ejemplo, su programa coincide con POSIX 1003.1 Issues 6 y usted definió un tipo foo_t. POSIX 1003.1 Issues 7 finalmente se lanza con un tipo recién definido foo_t. Su programa no coincide con la nueva versión, lo que podría ser un problema. Restringir el _tuso impide refactorizar el código. Por lo tanto, si apunta a un cumplimiento POSIX, definitivamente debe evitarlo _tcomo lo establece el Estándar.

Nota al margen: personalmente, trato de mantenerme en POSIX porque creo que ofrece buenos conceptos básicos para una programación limpia. Además, soy bastante aficionado a las pautas de Linux Coding Style (capítulo 5) . Hay algunas buenas razones por las cuales no usar typedef. ¡Espero que esto ayude!


18

Es una convención de nomenclatura estándar para tipos de datos, generalmente definida por typedefs. Una gran cantidad de código C que se ocupa de registros de hardware utiliza nombres estándar definidos por C99 para tipos de datos de tamaño fijo con y sin signo. Como convención, estos nombres están en un archivo de encabezado estándar (stdint.h) y terminan con _t.


11

Es solo una convención que significa "tipo". No significa nada especial para el compilador.


11

El _tno tiene inherentemente ningún significado especial. Pero ha sido de uso común agregar el _tsufijo a typedef's.

Es posible que esté más familiarizado con las prácticas comunes de C para nombrar variables ... Esto es similar a cómo es común pegar una AP en el frente para un puntero y usar un guión bajo frente a las variables globales (esto es un poco menos común) y utilizar los nombres de las variables i, jyk para variables de bucle temporal.

En el código donde el tamaño de las palabras y el orden son importantes, es muy común usar tipos definidos personalizados que son explícitos, como BYTE WORD(normalmente 16 bits) DWORD(32 bits).

int_tno es tan bueno, porque la definición de intvaría entre plataformas, entonces, ¿a quién intse está conformando? (Aunque, en la actualidad, la mayoría del desarrollo centrado en PC lo trata como 32 bits, muchas cosas para el desarrollo que no es para PC todavía tratan los int como 16 bits).



8

Hubo algunas buenas explicaciones sobre el tema. Solo para agregar otra razón para redefinir los tipos:

En muchos proyectos integrados, todos los tipos se redefinen para indicar correctamente el tamaño dado a los tipos y para mejorar la portabilidad en diferentes plataformas (es decir, compiladores de tipos de hardware).

Otra razón será hacer que su código sea portátil en diferentes sistemas operativos y evitar colisiones con los tipos existentes en el sistema operativo que está integrando en su código. Para esto, generalmente se agrega un prefijo único (como sea posible).

Ejemplo:

typedef unsigned long dc_uint32_t;

7

Si está tratando con un código de interfaz de hardware, el autor del código que está viendo podría haber definido int_tun número entero de tamaño específico. El estándar C no asigna un tamaño específico al inttipo (depende de su compilador y plataforma de destino, potencialmente), y el uso de un int_ttipo específico evitaría ese problema de portabilidad.

Esta es una consideración particularmente importante para el código de la interfaz de hardware, que puede ser la razón por la que primero ha notado la convención allí.


1
esto no será una muy buena práctica, esperaría que uno defina [u] int_ [32 16 8] _t para dejar en claro cuál es el tamaño que está definiendo.
Ilya

1
Tienes toda la razón, "int_t" por sí solo le dice al programador que es un tipo definido por el usuario, ¡pero no lo que realmente es!
Greg Hewgill

0

Por ejemplo en 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 siempre significa definido por typedef.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.