简体   繁体   English

C V C ++中的Typedef结构

[英]Typedef struct in C Vs C++

This gives an error in C++ but not in C: 这在C ++中给出了错误,但在C中没有:

typedef struct nodes
{
    int data;
    struct node *next;
}node;

It gives the following error in C++. 它在C ++中给出以下错误。

/home/DS cpp/linkedlist.cpp|10|error: conflicting declaration ‘typedef struct nodes node’|
/home/DS cpp/linkedlist.cpp|9|error: ‘struct node’ has a previous declaration as ‘struct node’|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

For it to work in C++ I have to change it to this: 要使它在C ++中工作,我必须将其更改为:

typedef struct node
{
    int data;
    struct node *next;
}node;

I don't understand why this happens, I want to know the order of execution in both C and C++ so that I can understand it. 我不明白为什么会发生这种情况,我想知道C和C ++中的执行顺序,以便我能理解它。

Let's analyse your code a bit: 让我们稍微分析一下你的代码:

typedef struct nodes
{
    int data;
    struct node *next;
}node;

This declares and defines struct nodes , a type with two members, and declares a type alias so we can refer to it only as node . 这声明并定义了struct nodes ,一个具有两个成员的类型,并声明了一个类型别名,因此我们只能将它称为node

Now, in C++, the member declaration struct node *next automatically forward-declares a type called node . 现在,在C ++中,成员声明struct node *next 自动转发声明一个名为node的类型 That then conflicts with your typedef target node : it's as if you're trying to give two types the same name. 然后与你的typedef目标node发生冲突:就好像你试图给两个类型的名字一样。

In C, there is no conflict, because the type called node can in fact only be referred to as struct node . 在C中,没有冲突,因为称为node的类型实际上只能称为struct node

The second snippet worked because, since during parsing of the member declaration struct node already exists, no new type is forward-declared there … and since all you're then doing is renaming it in the same typedef statement, C++ doesn't really care, knowing that it's all the same type ( struct T is T ; the difference is in syntax, not in name). 第二个片段起作用是因为,因为在解析成员声明struct node已经存在时,没有新的类型在那里被前向声明...并且因为你所做的就是在同一个typedef语句中重命名它,C ++并不真正关心,知道它是完全相同的类型( struct T T ;区别在于语法,而不是名称)。

[C++11: 7.1.3/3]: In a given non-class scope, a typedef specifier can be used to redefine the name of any type declared in that scope to refer to the type to which it already refers. [C++11: 7.1.3/3]:在给定的非类作用域中,可以使用typedef说明符重新定义在该作用域中声明的任何类型的名称,以引用它已引用的类型。 [ Example: [例如:

 typedef struct s { / ... / } s; typedef int I; typedef int I; typedef II; 

—end example ] - 末端的例子]

[C++11: 7.1.3/6]: In a given scope, a typedef specifier shall not be used to redefine the name of any type declared in that scope to refer to a different type. [C++11: 7.1.3/6]:在给定范围内, typedef说明符不得用于重新定义在该范围内声明的任何类型的名称以引用其他类型。 [ Example: [例如:

 class complex { / ... / }; typedef int complex; // error: redefinition 

—end example ] - 末端的例子]

Of course, in C++, this is all moot and you should just write: 当然,在C ++中,这一切都没有实际意义,你应该写:

struct node
{
   int data;
   node* next;
};

You do not need to typedef -away the elaborated-type-specifier struct . 你并不需要typedef -away的阐述类型说明符 struct

The C example you gave should be an error. 您提供的C示例应该是错误。 You're using a tag name ( node ) that you haven't defined with struct node . 您正在使用未使用struct node定义的标记名称( node )。

Given those two choices, the second is the one to use. 鉴于这两个选择,第二个是使用的选择。 I prefer a bit of economy: 我更喜欢经济:

typedef struct node_t
{
    int data;
    struct node_t *next;
} node_t;

In C or C++, the tag names have their own namespace, so there is no problem with using the same name for the tag and the typedef name. 在C或C ++中,标记名称具有自己的名称空间,因此对标记和typedef名称使用相同的名称没有问题。 In C, this allows you to use either node_t or struct node_t to refer to this struct type. 在C中,这允许您使用node_tstruct node_t来引用此结构类型。 C++ will search the tag names for a type name if a declared type name doesn't exist, so the above double-definition isn't needed, but doesn't hurt. 如果声明的类型名称不存在,C ++将在标记名称中搜索类型名称,因此不需要上面的双重定义,但不会受到影响。

In both languages, the explicit struct node_t version is required at any point before the type is completely defined, so any self-reference, and any forward references will use the struct version. 在这两种语言中,在完全定义类型之前的任何时候都需要显式struct node_t版本,因此任何自引用和任何前向引用都将使用struct版本。 I prefer this in header files, mostly because it reduces problems with order of #include directives. 我更喜欢在头文件中使用它,主要是因为它减少了#include指令顺序的问题。

PS: This does work in either language (see LRIO's answer for pointers into the C++11 Standard) and has been used in enough bilingual and even pure C++ header files that it's unlikely to disappear soon) so it's a very simple approach that just works in either language. PS:这样确实可以在任何一种语言(见LRIO对指针到C ++ 11标准答案),并在足够的双语甚至纯C ++头文件已被使用,它是不太可能很快消失),所以这是一个非常简单的方法,只是适用于任何一种语言。

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

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