类型后跟 _t(下划线-t)代表什么?
这似乎是一个简单的问题,但我无法通过 Stack Overflow 搜索或 Google 找到它。 类型后跟 _t
是什么意思? 例如,
int_t anInt;
我在 C 代码中经常看到它与硬件密切相关,我不禁认为它们是相关的。
This seems like a simple question, but I can't find it with the Stack Overflow search or Google. What does a type followed by a _t
mean? Such as
int_t anInt;
I see it a lot in C code meant to deal closely with hardware—I can't help but think that they're related.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
正如 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
,等等。 这些新类型在
中正式定义,但大多数情况下您将使用
,其中(对于标准 C 头文件来说不常见)包括
。 它 (
) 还定义了与printf()
和scanf()
一起使用的宏。正如 Matt Curtis 指出的,后缀对编译器来说没有任何意义; 这是一个以人为本的公约。
但是,您还应该注意 POSIX 定义了许多以 '
结尾的额外类型名称_t
',并保留后缀以供实现。 这意味着,如果您正在使用 POSIX 相关系统,那么使用约定定义您自己的类型名称是不明智的。 我所开发的系统已经做到了这一点(20 多年了); 我们经常会被系统定义与我们定义的名称相同的类型所困扰。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 assize_t
, the C89 standard defineswchar_t
,off_t
,ptrdiff_t
, and probably some others I've forgotten. The C99 standard defines a lot of extra types, such asuintptr_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 theprintf()
andscanf()
.As Matt Curtis noted, there is no significance to the compiler in the suffix; it is a human-oriented convention.
However, you should also note that POSIX defines a lot of extra type names ending in '
_t
', and reserves the suffix for the implementation. That means that if you are working on POSIX-related systems, defining your own type names with the convention is ill-advised. The system I work on has done it (for more than 20 years); we regularly get tripped up by systems defining types with the same name as we define._t
通常包装不透明的类型定义。GCC 仅将以
_t
结尾的名称添加到您可能不使用的保留命名空间中,以避免与标准 C 和 POSIX 的未来版本发生冲突 (GNU C 库手册)。 经过一番研究,我终于在 POSIX 标准 1003.1 中找到了正确的参考: B .2.12 数据类型(卷:基本原理,附录: B. 系统接口的基本原理,章节:B.2 一般信息):简而言之,标准表示有很好的机会扩展标准类型列表,因此标准限制
_t
命名空间供其自身使用。例如,您的程序匹配POSIX 1003.1 Issue 7并且您定义了类型
foo_t
。 POSIX 1003.1 Issue 8 最终以新定义的类型foo_t
发布。 您的程序与新版本不匹配,这可能是一个问题。 限制_t
使用可防止重构代码。 因此,如果您的目标是符合 POSIX,那么您绝对应该避免使用标准中规定的_t
。旁注:就我个人而言,我尝试坚持使用 POSIX,因为我认为它为干净的编程提供了良好的基础。 此外,我非常喜欢 Linux 编码风格 (第5章)指南。 不使用 typedef 有一些很好的理由。 希望这有帮助!
The
_t
usually wraps an opaque type definition.GCC merely add names that end with
_t
to the reserved namespace you may not use, to avoid conflicts with future versions of Standard C and POSIX (GNU C library manual). After some research, I finally found the correct reference inside the POSIX Standard 1003.1: B.2.12 Data Types (Volume: Rationale, Appendix: B. Rationale for System Interfaces, Chapter: B.2 General Information):In a nutshell, the Standard says that there are good chances of extending the Standard types' list, therefore the Standard restricts the
_t
namespace for its own use.For instance, your program matches POSIX 1003.1 Issue 7 and you defined a type
foo_t
. POSIX 1003.1 Issue 8 is eventually released with a newly defined typefoo_t
. Your program does not match the new version, which might be a problem. Restricting the_t
usage prevents from refactoring the code. Thus, if you aim to a POSIX compliancy, you should definitely avoid the_t
as the Standard states it.Side note: personally, I try to stick to POSIX because I think it gives good basics for clean programming. Moreover, I am pretty fond of Linux Coding Style (chapter 5) guidelines. There are some good reasons why not using typedef. Hope this help!
这是用于命名数据类型的约定,例如使用
typedef
:It's a convention used for naming data types, e.g with
typedef
:它是数据类型的标准命名约定,通常由 typedef 定义。 许多处理硬件寄存器的 C 代码使用 C99 定义的标准名称来表示有符号和无符号固定大小数据类型。 按照惯例,这些名称位于标准头文件 (stdint.h) 中,并以 _t 结尾。
It is a standard naming convention for data types, usually defined by typedefs. A lot of C code that deals with hardware registers uses C99-defined standard names for signed and unsigned fixed-size data types. As a convention, these names are in a standard header file (stdint.h), and end with _t.
_t
本质上没有任何特殊含义。 但在 typedef 中添加_t
后缀已经变得很常见。您可能更熟悉常见的 C 变量命名实践...这类似于通常将 ap 放在前面作为指针,并在全局变量前面使用下划线(这种情况不太常见) ,并使用变量名称
i
、j
和k
作为临时循环变量。在字大小和顺序很重要的代码中,通常使用显式的自定义定义类型,例如
BYTE
WORD
(通常为 16 位)DWORD
(32 位)。int_t
不太好,因为int
的定义在不同平台上有所不同——那么你遵循谁的int
呢? (尽管现在,大多数以 PC 为中心的开发将其视为 32 位,但许多非 PC 开发的东西仍然将 int 视为 16 位)。The
_t
does not inherently have any special meaning. But it has fallen into common use to add the_t
suffix to typedef's.You may be more familiar with common C practices for variable naming... This is similar to how it's common to stick a p at the front for a pointer, and to use an underscore in front of global variables (this is a bit less common), and to use the variable names
i
,j
, andk
for temporary loop variables.In code where word-size and ordering is important, it's very common to use custom defined types that are explicit, such as
BYTE
WORD
(normally 16-bit)DWORD
(32-bits).int_t
is not so good, because the definition ofint
varies between platforms -- so whoseint
are you conforming to? (Although, these days, most PC-centric development treats it as 32 bits, much stuff for non-PC development still treat int's as 16 bits).这只是一个约定,意思是“类型”。 这对编译器来说没有什么特别的意义。
It's just a convention which means "type". It means nothing special to the compiler.
就是类型的意思。
size_t
是尺码类型。It means type.
size_t
is the size type.关于这个主题有一些很好的解释。 只是添加重新定义类型的另一个原因:
在许多嵌入式项目中,所有类型都被重新定义,以正确说明给定的类型大小,并提高跨不同平台(即硬件类型编译器)的可移植性。
另一个原因是使您的代码可以跨不同操作系统移植,并避免与您在代码中集成的操作系统中的现有类型发生冲突。 为此,通常会添加一个唯一的(尽可能)前缀。
例子:
There were a few good explanations about the subject. Just to add another reason for re-defining the types:
In many embedded projects, all types are redefined to correctly state the given sizing to the types and to improve portability across different platforms (i.e hardware types compilers).
Another reason will be to make your code portable across different OSs and to avoid collisions with existing types in the OS that you are integrating in your code. For this, usually a unique (as possible) prefix is added.
Example:
如果您正在处理硬件接口代码,您正在查看的代码的作者可能已将
int_t
定义为特定大小的整数。 C 标准不会为int
类型分配特定的大小(这可能取决于您的编译器和目标平台),并且使用特定的int_t
类型可以避免这种情况可移植性问题。对于硬件接口代码来说,这是一个特别重要的考虑因素,这可能就是您首先注意到那里的约定的原因。
If you're dealing with hardware interface code, the author of the code you're looking at might have defined
int_t
to be a specific size integer. The C standard doesn't assign a specific size to theint
type (it depends on your compiler and target platform, potentially), and using a specificint_t
type would avoid that portability problem.This is a particularly important consideration for hardware interface code, which may be why you've first noticed the convention there.
例如,在 C99 中,/usr/include/stdint.h:
_t
始终表示由 typedef 定义。For example in C99, /usr/include/stdint.h:
_t
always means defined by typedef._t
表示“类型”。 将其与typedef
一起使用是一种常见的约定。我已经使用它很多年了,例如,在专业代码库中,如下所示:注意我对
timer_t
和timer_error_t
的使用:但是,我最近从 @Jonathan Leffler 的回答,POSIX 为其自己的类型保留
_t
后缀,我遇到了问题其中timer_t
已由 POSIX 定义,从而阻止上面的编译!G++ 编译时错误:
因此,我切换到这个新约定以避免使用 POSIX 保留的
_t
后缀。 我进行了以下更改,从而删除了对_t
的使用:这是最终结果:
推荐的结构和枚举命名约定,以避免重新定义由 保留的
_t
类型POSIX这一新约定避免了重叠使用
_t
的风险。_t
means "type". It's a common convention to use it withtypedef
s.I've been using it for years, for instance, in professional code bases, like this: notice my usage of
timer_t
andtimer_error_t
:However, I recently learned from @Jonathan Leffler's answer that POSIX reserves the
_t
suffix for its own types, and I ran into the problem wheretimer_t
is already defined by POSIX, preventing the above from compiling!G++ compile-time error:
So, I'm switching to this new convention to avoid using the
_t
suffix which is reserved by POSIX. I've made the following changes, thereby removing my usage of_t
:Here's the final result:
Recommended naming convention for structs and enums to avoid redefining
_t
types which are reserved by POSIXThis new convention avoids the risk of having overlapping usages of
_t
.