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

7 minutos de lectura

avatar de usuario
kevin grifo

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 _t ¿significar? Como

int_t anInt;

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

  • Dónde está int_t definido? Si siempre se define como int, no es útil; es mucho más claro de usar int directamente. Si no siempre se define como int (digamos, si pudiera ser long int o short int), entonces es un nombre mal elegido y confuso.

    –Keith Thompson

    24 de julio de 2015 a las 17:32

avatar de usuario
jonathan leffler

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

Como señaló Matt Curtis, no hay significado para el compilador en el sufijo; es una convención orientada a los humanos.

Sin embargo, también debe tener en cuenta que POSIX define muchos nombres de tipos adicionales que terminan en ‘_t‘, y se reserva el sufijo para la implementación. Eso significa que si está trabajando en sistemas relacionados con POSIX, no es recomendable 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 hacen tropezar los sistemas que definen tipos con el mismo nombre que definimos.

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

    – Juguetero

    23 de octubre de 2008 a las 22:38

  • Uso _type en lugar de _t en mis typedefs precisamente para evitar eso.

    – CesarB

    23 de octubre de 2008 a las 23:51

  • @Jonathan Leffler: ¿Qué convención de nomenclatura usaría para los tipos definidos por el usuario?

    – J.Andrew Laughlin

    18/04/2011 a las 21:43

  • @Andrew: si tiene una abreviatura conveniente para usar como prefijo, entonces puede usarla con seguridad abbr_xxxxx_t escriba nombres. Sin ese prefijo, es posible que lo atrapen en cualquier momento. En general, los estandarizados _t los tipos utilizan todas las minúsculas (FILE y DIR son dos excepciones, dos veces – todo en mayúsculas, y no _t), por lo que podría usar CamelCase_t con seguridad moderada, con o sin las tapas delanteras. El sistema en el que trabajo principalmente tiende a vivir peligrosamente y a usar _t en fin, pero nos ha picado en ocasiones. tiendo a usar CamelCase sin un sufijo para mi propio trabajo; mis funciones suelen estar todas en minúsculas.

    –Jonathan Leffler

    18/04/2011 a las 22:45

  • @JonathanLeffler, comencé a usar esa convención, CamelCase para tipos, minúsculas para funciones. Busqué esta pregunta esperando no ser el único. ¡Gracias por la validación!

    -Austin Mullins

    13 de junio de 2014 a las 22:26

avatar de usuario
Benoit

Él _t normalmente envuelve una definición de tipo opaca.

GCC simplemente agrega nombres que terminan con _t al 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 investigar un poco, finalmente encontré la referencia correcta dentro del estándar POSIX 1003.1: B.2.12 Tipos de datos (Volumen: Razón fundamentalApéndice: B. Justificación de las interfaces del sistemaCapítulo: B.2 Información general):

B.2.12 Tipos de datos
Tipos definidos

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 está definido por POSIX.1-2017) en un archivo de encabezado y usarlo en otro sin agregar símbolos al espacio de nombres del programa. Para permitir que los implementadores proporcionen sus propios tipos, todas las aplicaciones conformes deben evitar los símbolos que terminan en “_t”, lo que permite que el implementador proporcione tipos adicionales. Debido a que un uso importante de los tipos es en la definición de los miembros de la estructura, que pueden (y en muchos casos deben) agregarse a las estructuras definidas en POSIX.1-2017, la necesidad de tipos adicionales es apremiante.

En pocas palabras, la Norma dice que hay buenas posibilidades de ampliar la lista de tipos de la Norma, por lo que la Norma restringe la _t espacio de nombres para su propio uso.

Por ejemplo, su programa coincide POSIX 1003.1 Problema 7 y definiste un tipo foo_t. POSIX 1003.1 Problema 8 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. Restringiendo el _t el uso impide refactorizar el código. Por lo tanto, si su objetivo es cumplir con POSIX, definitivamente debe evitar el _t como dice la Norma.

Nota al margen: personalmente, trato de apegarme a POSIX porque creo que brinda buenos conceptos básicos para una programación limpia. Además, me gusta mucho Estilo de codificación de Linux (capítulo 5) pautas. Hay algunas buenas razones por las que no usar typedef. ¡Espero que esto ayude!

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

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


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

avatar de usuario
constructor de juguetes

Él _t no tiene inherentemente ningún significado especial. Pero se ha vuelto de uso común agregar el _t sufijo de typedef.

Es posible que esté más familiarizado con las prácticas comunes de C para la denominación de variables… Esto es similar a cómo es común colocar una ap al frente para un puntero y usar un guión bajo delante de las variables globales (esto es un poco menos común) , y para usar los nombres de las variables i, jy k para variables de bucle temporales.

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

int_t no es tan bueno, porque la definición de int varía entre plataformas, por lo que de quién int te estás conformando? (Aunque, en estos días, la mayoría del desarrollo centrado en PC lo trata como 32 bits, muchas cosas para el desarrollo que no es de PC todavía tratan los int como 16 bits).

avatar de usuario
Jamal

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 entre 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 (lo más posible).

Ejemplo:

typedef unsigned long dc_uint32_t;

avatar de usuario
jayhola

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.

¿Ha sido útil esta solución?