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)
In the first case, your struct has two equivalent names:
struct Element(whereElementis a struct tag) andElement(whereElementis 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 Elementin the declaration of thenextmember.In that context,
struct Elementis an incomplete type. You can’t declare objects of incomplete types, but you can declare pointers to them.The declaration
is legal, but it doesn’t make
nexta 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, notElement, within the definition itself, since the typedef nameElementisn’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
structkeyword.Another alternative is to separate the typedef from the struct definition:
(You can use an incomplete type name in a
typedef.)