C 后跟_t(下划线-t)的类型代表什么?

C 后跟_t(下划线-t)的类型代表什么?,c,naming-conventions,types,C,Naming Conventions,Types,这似乎是一个简单的问题,但我无法在Stack Overflow搜索或Google中找到它。类型后跟\t是什么意思?比如 int_t anInt; 我在C代码中经常看到它,它意味着与硬件密切相关,我忍不住认为它们是相关的。它意味着类型大小\u t是大小类型。这只是一个表示“类型”的约定。它对编译器没有什么特殊意义。这是一种用于命名数据类型的约定,例如使用typedef: typedef struct { char* model; int year; ... } car_t; 如果您正

这似乎是一个简单的问题,但我无法在Stack Overflow搜索或Google中找到它。类型后跟
\t
是什么意思?比如

int_t anInt;

我在C代码中经常看到它,它意味着与硬件密切相关,我忍不住认为它们是相关的。

它意味着类型<代码>大小\u t是大小类型。

这只是一个表示“类型”的约定。它对编译器没有什么特殊意义。

这是一种用于命名数据类型的约定,例如使用
typedef


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

如果您正在处理硬件接口代码,那么您正在查看的代码的作者可能已将
int\u t
定义为特定大小的整数。C标准没有为
int
类型指定特定的大小(这可能取决于编译器和目标平台),使用特定的
int\u t
类型可以避免可移植性问题


这对于硬件接口代码来说是一个特别重要的考虑因素,这可能是您第一次注意到这里的约定的原因。

正如Douglas Mayle所指出的,它基本上表示类型名称。因此,不建议您以“
\u t
”结尾变量或函数名,因为这可能会引起一些混淆。除了
size\u t
,C89标准还定义了
wchar\u t
off\u t
ptrdiff\u t
,可能还有其他一些我已经忘记的。C99标准定义了许多额外的类型,例如
uintpttr\t
intmax\t
int8\u t
uint\u least16\u t
uint\u fast32\u t
,等等。这些新类型是在
中正式定义的,但大多数情况下,您将使用
,其中包括
。它(
)还定义了用于
printf()
scanf()
的宏

正如马特·柯蒂斯所指出的,后缀对编译器没有意义;这是一项以人为本的公约


但是,您还应该注意,它定义了许多以“
\u t
”结尾的额外类型名,并且为实现保留后缀。这意味着,如果您在POSIX相关系统上工作,使用约定定义自己的类型名是不明智的。我工作的系统已经做到了这一点(超过20年);我们经常被定义与我们定义的名称相同的类型的系统绊倒。

这是数据类型的标准命名约定,通常由typedef定义。许多处理硬件寄存器的C代码使用C99定义的标准名称来表示有符号和无符号的固定大小数据类型。按照惯例,这些名称位于标准头文件(stdint.h)中,并以_t结尾。

\u t
本身没有任何特殊含义。但在typedef中添加
\u t
后缀已成为常用

您可能更熟悉变量命名的常见C实践。。。这类似于在指针前面粘贴一个p,在全局变量前面使用下划线(这不太常见),以及在临时循环变量中使用变量名
i
j
k

在字长和顺序很重要的代码中,使用自定义定义的显式类型是非常常见的,例如
字节
word
(通常为16位)
DWORD
(32位)


int\u t
不太好,因为
int
的定义在不同的平台上有所不同——那么您遵循的是谁的
int
?(尽管现在大多数以PC为中心的开发都将其视为32位,但许多非PC开发的东西仍然将int视为16位)

关于这个问题有一些很好的解释。仅添加重新定义类型的另一个原因:

在许多嵌入式项目中,所有类型都被重新定义,以正确地表示类型的给定大小,并提高跨不同平台(即硬件类型编译器)的可移植性

另一个原因是使您的代码能够跨不同的操作系统进行移植,并避免与集成在代码中的操作系统中的现有类型发生冲突。为此,通常会添加唯一的(尽可能)前缀

例如:

typedef unsigned long dc_uint32_t;

\u t
通常包装不透明的类型定义

GCC只是将以
\u t
结尾的名称添加到您可能不使用的保留名称空间中,以避免与标准C和POSIX的未来版本发生冲突。经过一些研究,我终于在POSIX标准1003.1(卷:,附录:,章节:)中找到了正确的参考:

B.2.12数据类型
定义的类型
本节中定义的其他类型以“\u t”结尾的要求是由名称空间污染问题引起的。在一个头文件中定义一个类型(该类型不是POSIX.1-2017定义的类型)并在另一个头文件中使用,而不向程序的名称空间添加符号,这是很困难的。为了允许实现者提供自己的类型,所有符合要求的应用程序都需要避免以“\u t”结尾的符号,这允许实现者提供其他类型。由于类型的主要用途是在结构构件的定义中,结构构件可以(并且在许多情况下必须)添加到POSIX.1-2017中定义的结构中,因此迫切需要额外的类型

简言之,该标准指出,扩展标准类型列表的可能性很大,因此该标准限制了
\t
名称空间供自己使用

例如,您的程序与POSIX 1003.1第7版匹配,并且您定义了一个类型
foo\u t
。POSIX 1003.1第8版最终发布了一个新定义的类型
foo\u t
。您的程序与新版本不匹配,这可能是一个问题。限制
\u t
使用可防止
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