这似乎是一个简单的问题,但我用Stack Overflow搜索或谷歌找不到它。类型后面跟着_t是什么意思?如
int_t anInt;
我在C代码中经常看到这种情况,这些代码是为了紧密地处理硬件——我忍不住认为它们是相关的。
这似乎是一个简单的问题,但我用Stack Overflow搜索或谷歌找不到它。类型后面跟着_t是什么意思?如
int_t anInt;
我在C代码中经常看到这种情况,这些代码是为了紧密地处理硬件——我忍不住认为它们是相关的。
这是一种用于命名数据类型的约定,例如使用typedef:
typedef struct {
char* model;
int year;
...
} car_t;
如果您正在处理硬件接口代码,您正在查看的代码的作者可能已经将int_t定义为一个特定大小的整数。C标准没有为int类型分配特定的大小(这可能取决于您的编译器和目标平台),使用特定的int_t类型可以避免可移植性问题。
对于硬件接口代码,这是一个特别重要的考虑因素,这可能就是为什么您第一次注意到这里的约定。
As Douglas Mayle noted, it basically denotes a type name. Consequently, you would be ill-advised to end variable or function names with '_t' since it could cause some confusion. As well as size_t, the C89 standard defines wchar_t, off_t, ptrdiff_t, and probably some others I've forgotten. The C99 standard defines a lot of extra types, such as uintptr_t, intmax_t, int8_t, uint_least16_t, uint_fast32_t, and so on. These new types are formally defined in <stdint.h> but most often you will use <inttypes.h> which (unusually for standard C headers) includes <stdint.h>. It (<inttypes.h>) also defines macros for use with the printf() and scanf().
正如Matt Curtis所指出的,后缀对编译器没有任何意义;这是一个以人为本的惯例。
但是,您还应该注意到POSIX定义了许多以'_t'结尾的额外类型名,并为实现保留了后缀。这意味着如果您在posix相关的系统上工作,那么使用约定定义自己的类型名是不明智的。我工作的系统已经做到了(超过20年);我们经常会因为系统定义的类型与我们定义的名称相同而出错。
它是数据类型的标准命名约定,通常由typedefs定义。很多处理硬件寄存器的C代码使用c99定义的固定大小有符号和无符号数据类型的标准名称。作为约定,这些名称在标准头文件(stdint.h)中,并以_t结尾。
_t本身没有任何特殊含义。但是在typedef的后缀中添加_t已经成为一种常见的用法。
您可能更熟悉变量命名的常见C实践…这类似于在指针前面加一个p,在全局变量前面加一个下划线(这种情况不太常见),以及使用变量名i、j和k作为临时循环变量。
在字长和顺序很重要的代码中,通常使用显式的自定义类型,例如BYTE WORD(通常是16位)DWORD(32位)。
Int_t不是很好,因为int的定义在不同平台之间是不同的——那么你遵从谁的int呢?(尽管现在大多数以pc为中心的开发都将int视为32位,但许多非pc开发仍然将int视为16位)。
关于这个问题有一些很好的解释。再补充一个重新定义类型的原因:
在许多嵌入式项目中,所有类型都被重新定义,以正确地声明类型的给定大小,并提高跨不同平台(即硬件类型编译器)的可移植性。
另一个原因是让你的代码可以跨不同的操作系统移植,并避免与你在代码中集成的操作系统中的现有类型发生冲突。为此,通常会添加一个惟一的(尽可能的)前缀。
例子:
typedef unsigned long dc_uint32_t;
_t通常包装不透明类型定义。
GCC只是将以_t结尾的名称添加到您可能不使用的保留名称空间中,以避免与Standard C和POSIX (GNU C库手册)的未来版本冲突。经过一番研究,我终于在POSIX标准1003.1中找到了正确的参考:B.2.12数据类型(卷:基本原理,附录:B.系统接口的基本原理,章节:B.2一般信息):
B.2.12 Data Types Defined Types The requirement that additional types defined in this section end in "_t" was prompted by the problem of name space pollution. It is difficult to define a type (where that type is not one defined by POSIX.1-2017) in one header file and use it in another without adding symbols to the name space of the program. To allow implementors to provide their own types, all conforming applications are required to avoid symbols ending in "_t", which permits the implementor to provide additional types. Because a major use of types is in the definition of structure members, which can (and in many cases must) be added to the structures defined in POSIX.1-2017, the need for additional types is compelling.
简而言之,标准说有很好的机会扩展标准类型的列表,因此标准限制了_t命名空间供自己使用。
例如,您的程序匹配POSIX 1003.1 Issue 7,并且您定义了类型foo_t。POSIX 1003.1第8版最终发布了一个新定义的类型foo_t。您的程序与新版本不匹配,这可能是一个问题。限制_t的使用可以防止代码重构。因此,如果您的目标是POSIX遵从性,那么您绝对应该避免使用标准中规定的_t。
旁注:就我个人而言,我试图坚持使用POSIX,因为我认为它为简洁的编程提供了良好的基础。此外,我非常喜欢Linux编码风格(第5章)指南。有一些很好的理由不使用typedef。希望这对你有所帮助!
例如,在C99中,/usr/include/ stdt .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定义。