简体   繁体   English

为什么要定义一个_struct然后不使用_对其进行类型定义?

[英]Why define a _struct and then typedef it without _?

I was browsing the libgphoto2 repositories and saw this: 我正在浏览libgphoto2存储库,并看到了以下内容:

struct _PTPObjectHandles {
    uint32_t n;
    uint32_t *Handler;
};
typedef struct _PTPObjectHandles PTPObjectHandles;

Why would somebody want do that instead of just calling the struct PTPObjectHandles and omitting the whole typedef line? 为什么有人要这样做,而不是仅仅调用struct PTPObjectHandles并省略整个typedef行?

EDIT: I should probably note that _PTPObjectHandles is never again used in the code. 编辑:我可能应该注意到_PTPObjectHandles不再在代码中使用。

The most common reason for doing this is simply to make it shorter to type and begin to look like a "real data type". 这样做的最常见原因只是使它的键入更短,并开始看起来像“真实数据类型”。

EG, this: EG,这:

struct _PTPObjectHandles *ptr1;
int something;
struct _PTPObjectHandles *ptr2;

Simply looks "cooler" if you rewrite it as: 如果将其重写为:

PTPObjectHandles *ptr1;
int something;
PTPObjectHandles *ptr2;

That's the main reason. 那是主要原因。

However, it also provides the library developer that is making you use it the ability to re-typedef it as something else in the future. 但是,它还为库开发人员提供了使您使用它的能力,以便将来将其重新定义为其他类型。 I've seen cases (eg, OpenSSL) that changed a typedef from a real struct to a pointer to a struct (for example). 我已经看到了一些案例(例如OpenSSL),这些案例将typedef从实际结构更改为指向结构的指针(例如)。 (Granted, that didn't work, but you can imagine the case where a typedef does actually change and it would work.) (当然,这是行不通的,但是您可以想象出typedef确实发生了更改并且可以工作的情况。)

So, do you have to? 所以,你必须吗? No. 没有。

Do people do it to try and make code more readable? 人们是否会尝试使代码更具可读性? Yes. 是。

Note that a C++ class is actually doing about the same thing. 请注意,C ++类实际上在做同一件事。 If you go read a good C++ from the ground up kind of book, you'll find it first starting with a struct and then changing the 'struct' word to 'class' and starting to instantiate it using the straight name. 如果您从一本书开始读一本优秀的C ++,您会发现它首先是从一个struct开始,然后将“ struct”一词更改为“ class”,并开始使用直接名称实例化它。

Edit: And... make sure you read the comment from @Bathsheba below and check proper naming conventions within C. As he points out, it should be _pTPObjectHandles with a lower-case p. 编辑:并且...确保您阅读了下面@Bathsheba的注释,并检查了C中的正确命名约定。正如他指出的那样,它应该是_pTPObjectHandles,小写的p。 For my own style, I avoid using uppercase typedefs too simply because I like my upper-case types to be true classes in C++ and want to know when they're just typedefs. 对于我自己的样式,我避免太简单地使用大写typedef,因为我喜欢大写类型在C ++中成为真正的类,并且想知道它们何时只是typedef。 But, again, that's a style choice. 但这又是一种风格选择。

It's partly so you can forward reference the structure inside itself but also use a meaningful name in the rest of the code, this: 部分原因是您可以向前引用其内部的结构,还可以在其余代码中使用有意义的名称,这是:

struct _mylist
{
    struct _mylist *next;
    /* etc ... */
};

typedef struct _mylist MyList;

Note that switching the order round makes things a little more readable, but you still need the two declarations, thus: 请注意,切换顺序使事情更具可读性,但是您仍然需要两个声明,因此:

typedef struct _mylist MyList;

struct _mylist
{
    MyList *next;
    /* etc ... */
};

What you can't do is this: 您不能执行以下操作:

typedef struct { MyList *next; } MyList;

so you have to have the 2 declarations. 所以你必须有两个声明。

I tend to use something similar to the first form, like this: 我倾向于使用类似于第一种形式的东西,例如:

typedef struct _mylist
{
    struct _mylist *next;
    /* etc ... */
} MyList;

as it makes it fairly clear the two types are meant to be the same. 因为很清楚,这两种类型的含义是相同的。

after that line of code, you can create struct by just using PTPObjectHandles . 在那行代码之后,您可以仅使用PTPObjectHandles创建结构。 creating that struct 创建那个结构

without typedef struct _PTPObjectHandles aStruct; 没有typedef struct _PTPObjectHandles aStruct;
with typedef: PTPObjectHandles aStruct; 使用typedef: PTPObjectHandles aStruct;

This pattern is used to say " _PTPObjectHandles is an internal (technical) name, don't use it. Use PTPObjectHandles instead." 该模式用来表示“ _PTPObjectHandles是内部(技术上的)名称,请不要使用它。请改用PTPObjectHandles 。”

Generally, in C, a leading underscore means "this is internal, go away". 通常,在C语言中,前导下划线表示“这是内部的,要消失”。 It's a cheap solution for a language that doesn't have proper name spaces (note: I'm talking about plain C here, not C++). 对于没有适当名称空间的语言,这是一种廉价的解决方案(请注意:我在这里谈论的是纯C,而不是C ++)。

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

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