简体   繁体   English

Typedef结构声明为两种类型:“typedef struct x {..} X,* XPointer”

[英]Typedef struct declared as two types: “typedef struct x { .. } X, *XPointer”

Sorry if this has been asked before, I wasn't really even sure what to search for to come up with this. 对不起,如果之前有人询问,我甚至不确定要搜索什么来提出这个问题。

When I create a typedef struct , I usually do something like this: 当我创建一个typedef struct ,我通常做这样的事情:

typedef struct myStruct {
  int a;
  int b;
  struct myStruct *next;
} MyStruct;

So I declare it with MyStruct at the end. 所以我最后用MyStruct声明它。 Then when I create functions that pass that in as a parameter, I write 然后,当我创建将其作为参数传递的函数时,我写道

int doSomething(MyStruct *ptr){

}

Yet I am collaborating with a friend on a project and I have come across his coding style, which is to also declare *MyStructP like this: 然而,我对一个项目的朋友合作,我所遇到他的编码风格,这宣告*MyStructP是这样的:

typedef struct myStruct {
  int a;
  int b;
  struct myStruct *next;
} MyStructR, *MyStructP;

And then he uses MyStructP in his functions, so his parameters look like: 然后他在他的函数中使用MyStructP ,所以他的参数看起来像:

int doSomething(MyStructP)

So he doesn't have to use the * in the parameter list. 所以他不必在参数列表中使用* This confused me because when I look at the parameter list, I always look for the * to determine if the arg is a pointer or not. 这让我很困惑,因为当我查看参数列表时,我总是寻找*以确定arg是否是指针。 On top of that, I am creating a function that takes in a struct I created and a struct he created, so my arg has the * and his does not. 最重要的是,我正在创建一个函数,它接受我创建的结构和他创建的结构,所以我的arg有*而他的没有。 Ultra confusing!! 超级混乱!!

Can someone give insight/comparison/advice on the differences between the two? 有人可以就两者之间的差异提供见解/比较/建议吗? Pros? 优点? Cons? 缺点? Which way is better or worse, or more widely used? 哪种方式更好或更差,还是更广泛使用? Any information at all. 任何信息都可以。 Thanks! 谢谢!

It is generally considered poor style to hide pointers behind typedefs, unless they are meant to be opaque handles (for example SDL_GLContext is a void* ). 通常认为在typedef后面隐藏指针的风格很差,除非它们是不透明的句柄(例如SDL_GLContextvoid* )。
This being not the case here, I agree with you that it's more confusing than helping. 这不是这里的情况,我同意你的看法,它比帮助更令人困惑。

The Linux kernel coding style says to avoid these kinds of typedefs: Linux内核编码风格说要避免这些类型的def:

Chapter 5: Typedefs 第5章:Typedef

Please don't use things like "vps_t". 请不要使用“vps_t”之类的东西。

It's a mistake to use typedef for structures and pointers. 将typedef用于结构和指针是错误的 When you see a 当你看到一个

 vps_t a; 

in the source, what does it mean? 在源头,这是什么意思?

In contrast, if it says 相反,如果它说

 struct virtual_container *a; 

you can actually tell what "a" is. 你实际上可以告诉“a”是什么。

Some people like to go with ideas from Hungarian Notation when they name variables. 有些人喜欢在他们命名变量时使用匈牙利表示法的想法。 And some people take that concept further when they name types. 有些人在命名类型时会进一步采用这个概念。

I think it's a matter of taste. 我认为这是一个品味问题。

However, I think it obscures things (like in your example) because you'd have to dig up the declaration of the name in order to find its type. 但是,我认为它模糊了事物(比如你的例子),因为你必须挖掘名称声明才能找到它的类型。 I prefer things to be obvious and explicit, and I would avoid such type names. 我更喜欢明显和明确的东西,我会避免这种类型的名称。

(And remember, typedef does not introduce a new type but merely a new name that aliases a new type.) (请记住, typedef不会引入新类型,而只会引入一个新类型的新名称。)

The main good reason why people occasionally typedef pointers is to represent the type as a "black box object" to the programmer and to allow its implementation to more easily be changed in the future. 人们偶尔使用typedef指针的主要原因是将类型表示为程序员的“黑盒子对象”,并允许将来更容易地更改其实现。

For example, maybe today the type is a pointer to a struct but tomorrow the type becomes an index into some table, a handle/key of some sort, or a file descriptor. 例如,今天可能类型是指向结构的指针,但明天该类型将成为某些表的索引,某种类型的句柄/键或文件描述符。 Typedef'ing this way tells the programmer that they shouldn't try things they might normally do to a pointer such as comparing it against 0 / NULL, dereferencing it (eg - directly accessing members), incrementing it, etc., as their code may become broken in the future. Typedef这样告诉程序员他们不应该尝试他们通常对指针做的事情,比如将它与0 / NULL进行比较,解除引用它(例如 - 直接访问成员),递增它等等,作为它们的代码将来可能会被打破。 Of course, using a naming convention, such as your friend did, that reveals and encodes that the underlying implementation actually is a pointer conflicts with that purpose. 当然,使用命名约定(例如您的朋友),会显示并编码底层实现实际上是指针与此目的冲突。

The other reason to do this is to make this kind of error less likely: 这样做的另一个原因是不太可能出现这种错误:

myStructR *ptr1, ptr2;
myStructP  ptr3, ptr4;

That's pretty weak sauce as the compiler will typically catch you misusing ptr2 later, but that is a reason given for doing this. 这是非常弱的问题,因为编译器通常会在以后捕获您滥用ptr2 ,但这是执行此操作的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM