这似乎是一个简单的问题,但我无法通过 Stack Overflow 搜索或 Google 找到它。一个类型后跟一个_t
意思是什么?如
int_t anInt;
我在旨在密切处理硬件的 C 代码中看到了很多——我不禁认为它们是相关的。
这似乎是一个简单的问题,但我无法通过 Stack Overflow 搜索或 Google 找到它。一个类型后跟一个_t
意思是什么?如
int_t anInt;
我在旨在密切处理硬件的 C 代码中看到了很多——我不禁认为它们是相关的。
正如 Douglas Mayle 所指出的,它基本上表示一个类型名称。因此,不建议您使用 ' _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>
which(通常用于标准 C 头文件)包括<stdint.h>
. 它 ( <inttypes.h>
) 还定义了与printf()
and一起使用的宏scanf()
。
正如 Matt Curtis 所指出的,后缀中的编译器没有意义;这是一个以人为本的公约。
但是,您还应该注意,POSIX定义了许多以 ' ' 结尾的额外类型名称_t
,并为实现保留了后缀。这意味着,如果您正在使用与 POSIX 相关的系统,那么使用约定定义您自己的类型名称是不明智的。我工作的系统已经做到了(超过 20 年);我们经常被定义与我们定义的名称相同的类型的系统绊倒。
这是用于命名数据类型的约定,例如typedef
:
typedef struct {
char* model;
int year;
...
} car_t;
_t
通常包装一个不透明的类型定义。
GCC 只是添加以您可能不使用的保留命名空间结尾_t
的名称,以避免与标准 C 和 POSIX (GNU C 库手册)的未来版本发生冲突。经过一番研究,我终于在 POSIX Standard 1003.1: B.2.12 Data Types (Volume: Rationale , Annex: B. Rationale for System Interfaces , Chapter: B.2 General Information ) 中找到了正确的参考:
B.2.12 数据类型
定义类型
本节中定义的附加类型以“_t”结尾的要求是由名称空间污染问题引起的。很难在一个头文件中定义一种类型(该类型不是 POSIX.1-2017 定义的类型)并在另一个头文件中使用它而不在程序的名称空间中添加符号。为了允许实现者提供他们自己的类型,所有符合要求的应用程序都必须避免以“_t”结尾的符号,这允许实现者提供额外的类型。由于类型的主要用途是定义结构成员,可以(并且在许多情况下必须)将其添加到 POSIX.1-2017 中定义的结构中,因此对其他类型的需求非常迫切。
简而言之,标准说有很好的机会扩展标准类型的列表,因此标准限制_t
命名空间供自己使用。
例如,您的程序匹配POSIX 1003.1 第 7 版,并且您定义了一个 type foo_t
。POSIX 1003.1 第 8 版最终以新定义的类型发布foo_t
。您的程序与新版本不匹配,这可能是个问题。限制_t
使用可以防止重构代码。因此,如果您的目标是符合 POSIX 标准,那么您绝对应该避免_t
按照标准的规定。
旁注:就个人而言,我尝试坚持使用 POSIX,因为我认为它为干净的编程提供了良好的基础。此外,我非常喜欢Linux 编码风格(第 5 章)指南。不使用 typedef 有一些很好的理由。希望这有帮助!
它是数据类型的标准命名约定,通常由 typedefs 定义。许多处理硬件寄存器的 C 代码使用 C99 定义的标准名称来表示有符号和无符号的固定大小数据类型。作为约定,这些名称位于标准头文件 (stdint.h) 中,并以 _t 结尾。
本质上_t
没有任何特殊含义。但是将_t
后缀添加到 typedef 已成为普遍使用。
您可能更熟悉用于变量命名的常见 C 实践......这类似于将 ap 粘贴在指针前面以及在全局变量前面使用下划线的常见方式(这不太常见) , 和 使用变量名i
, j
, 和k
临时循环变量。
在字长和顺序很重要的代码中,使用明确的自定义类型是很常见的,例如BYTE
WORD
(通常为 16 位)DWORD
(32 位)。
int_t
不太好,因为int
平台之间的定义不同 - 那么int
你符合谁?(尽管如今,大多数以 PC 为中心的开发都将其视为 32 位,但非 PC 开发的许多东西仍将 int 视为 16 位)。
这意味着类型。 size_t
是尺寸类型。
这只是一个约定,意思是“类型”。这对编译器没有什么特别的意义。
关于这个主题有一些很好的解释。只是为了添加重新定义类型的另一个原因:
在许多嵌入式项目中,所有类型都被重新定义,以正确地说明类型的给定大小并提高跨不同平台(即硬件类型编译器)的可移植性。
另一个原因是使您的代码可跨不同的操作系统移植,并避免与您在代码中集成的操作系统中的现有类型发生冲突。为此,通常会添加一个唯一(尽可能)的前缀。
例子:
typedef unsigned long dc_uint32_t;
如果您正在处理硬件接口代码,您正在查看的代码的作者可能已定义int_t
为特定大小的整数。C 标准没有为int
类型分配特定的大小(它可能取决于您的编译器和目标平台),并且使用特定int_t
类型可以避免这种可移植性问题。
对于硬件接口代码来说,这是一个特别重要的考虑因素,这可能是您首先注意到那里的约定的原因。
例如在 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 定义。