Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
347 views
in Technique[技术] by (71.8m points)

c - Why does "typdef struct { struct S *s; } S;" containing a pointer to same type compile?

I'm trying to typedef a struct which contains a pointer to another of the same type.

Thats what I thought would be the best version:

typedef struct Element
{
    char value;
    struct Element *next;
} Element;

Why is that variant also compiling + executing?:

typedef struct
{
    char value;
    struct Element *next;
} Element;

To describe the first I'd say: "Name struct Element Element now" and the second as: "Take this anonymous struct and call it Element"

But why can I still declare a struct Element (inside the struct) in the second case?

(Working in GCC and MSVC)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In the first case, your struct has two equivalent names: struct Element (where Element is a struct tag) and Element (where Element is a typedef, an alias for an existing type).

In the second case, you just didn't define a tag for the struct. Normally that would be perfectly valid, but here you're referring to the nonexistent type struct Element in the declaration of the next member.

In that context, struct Element is an incomplete type. You can't declare objects of incomplete types, but you can declare pointers to them.

The declaration

typedef struct
{
    char value;
    struct Element *next;
} Element;

is legal, but it doesn't make next a pointer to the enclosing type. It makes it a pointer to some incomplete type, and you won't be able to refer to it until and unless you declare the full type.

Your second declaration is one of the plethora of things that don't make sense, but are still legal C.

You might consider just omitting the typedef and consistently referring to the type as struct Element. As lot of people like the convenience of having a one-word name for a structure type, but my own personal opinion is that there's not much benefit to that (unless the type is truly opaque, i.e., users of the type don't even know it's a struct). It's a matter of style.

Note that you need to refer to the type as struct Element, not Element, within the definition itself, since the typedef name Element isn't visible yet.

The fact that the struct tag and the typedef have the same name may seem confusing, but it's perfectly legititimate. Struct tags and typedefs are in separate namespaces (in the C sense, not the C++ sense); a struct tag can only appear immediately after the struct keyword.

Another alternative is to separate the typedef from the struct definition:

typedef struct Element Element;

struct Element {
    char value;
    Element *next;
};

(You can use an incomplete type name in a typedef.)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...