结构体的typedef最佳实践?

huangapple go评论57阅读模式
英文:

Best practice for typedef'ing structs?

问题

I've gone down a rabbit hole of questions about typedef, tag and struct namespaces, and leading _ being reserved by either the system libraries or the compilers. My question:

令人困惑的问题,关于typedef、标签和结构体的命名空间,以及前导_是否被系统库或编译器保留。我的问题是:

What is the best practice for typedef'ing structs?

在对结构体进行typedef时,最佳实践是什么?

For example, here are some possibilities:

例如,以下是一些可能的选项:

typedef struct ll_item {...} ll_item;
typedef struct _ll_item {...} ll_item;
typedef struct ll_item {...} ll_item_type;
typedef struct ll_item {...} LLItemType;

Anyone have experience in which is typically used, and most standard? I've seen textbooks use the leading underscore method for the structure name itself (and I would intuitively use that method as well), but could that pollute that namespace if a system struct uses that name?

有人有经验,通常使用哪种方式,哪种方式最标准?我曾看到教材使用前导下划线方法用于结构体名称本身(我也会直觉地使用该方法),但如果系统的struct使用了该名称,是否会污染命名空间?

英文:

I've gone down a rabbit hole of questions about typedef, tag and struct namespaces, and leading _ being reserved by either the system libraries or the compilers. My question:

What is the best practice for typedef'ing structs?

For example, here are some possibilities:

typedef struct ll_item {...} ll_item;
typedef struct _ll_item {...} ll_item;
typedef struct ll_item {...} ll_item_type;
typedef struct ll_item {...} LLItemType;

Anyone have experience in which is typically used, and most standard? I've seen textbooks use the leading underscore method for the structure name itself (and I would intuitively use that method as well), but could that pollute that namespace if a system struct uses that name?

答案1

得分: 2

这都相对而言。具有前导下划线的标识符绝对是不良实践,因为它可能与标准库/编译器内部发生冲突,请参阅C 7.1.3:

所有以下划线开头的标识符始终保留供在普通和标签名称空间中用作文件范围标识符的使用。

实际上,最常见的做法是根本不使用结构体标签。只有一些特殊情况需要它们,比如自引用结构体和不透明类型等。基于此,我主观地说,以下任何一个都是“最佳”选择:

typedef struct {...} ll_item;
typedef struct ll_item {...} ll_item;

因为struct ll_item(结构体标签版本)和ll_item(typedef版本)都引用了相同的对象类型,即使它们存在于不同的命名空间中。struct ll_itemll_item是兼容的类型。

自引用结构体将如下所示:

typedef struct ll_item 
{
  ...
  struct ll_item* next;
} ll_item;

不透明类型的前向声明如下:

typedef struct ll_item ll_item;

然后,不透明类型的定义(私有)将不使用typedef,但引用相同的类型:

struct ll_item { ... };

至于命名,那只取决于您的编码标准。ll_item_type也可以,即使您不关心POSIX,ll_item_t也可以。

英文:

This is all rather subjective. An identifier with a leading underscore is definitely bad practice, as may collides with the standard library/compiler internals, see C 7.1.3:

> All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.

The most common practice is actually not to use a struct tag at all. There are just a few special cases where they are actually needed, such as self-referencing structs and opaque types etc. Based on that I'd subjectively say that either of these are "best":

typedef struct {...} ll_item;
typedef struct ll_item {...} ll_item;

Because both struct ll_item (struct tag version) and ll_item (typedef version) refers to the same object type, even though they happen to exist in different namespaces. struct ll_item and ll_item are compatible types.

A self-referencing struct would then look like:

typedef struct ll_item 
{
  ...
  struct ll_item* next;
} ll_item;

An opaque type forward declaration would look like:

typedef struct ll_item ll_item;

And an opaque type definition (private) will then not use typedef but refer to the same type:

struct ll_item { ... };

As for naming, that's just according to your coding standard. ll_item_type would be fine too, and even ll_item_t if you don't care about POSIX.

huangapple
  • 本文由 发表于 2023年6月9日 14:49:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76437859.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定