0

Got confuse of a C++ code snippet when I study C++, Could someone help me on this? Thanks In advance.

struct LinkNode { int data; struct LinkNode* next; // Why there use `struct` type define LinkNode again? }; 

As my comments, why there use struct type define LinkNode again? I think code struct LinkNode{} had already define a LinkNode. Of course, if I change the code as below, it works fine without any compilation error either.

struct LinkNode { int data; LinkNode* next; // No any compilation errors either. }; 
4
  • There should be no error for the 1st version, both are equivalent. Can you show the complete example, as well as the exact error message? Commented Jun 16, 2020 at 15:02
  • 2
    The first is what recovering C programmers write before they've kicked the habit. It's not a redefinition. Commented Jun 16, 2020 at 15:05
  • @cigien Yes, there is no error message during compile. I just confuse why there use struct "declare"(I thought it's declare) LinkNode again what means type redefinition. Commented Jun 17, 2020 at 1:14
  • No, it's an optional usage of struct. It's not a redeclaration. Check out "elaborated type specifiers". Commented Jun 17, 2020 at 1:20

2 Answers 2

1

Type Redefinition of Struct In C++?

This is not a type redefinition. This is called an elaborated type specifier. It can be used to disambiguate a class name from another name that hides it. It is not necessary to use it in this case. It also doesn't break anything to use it.

The code may be written for an API usable from C as well. In C, this is necessary.

Sign up to request clarification or add additional context in comments.

Comments

1

In the code

struct LinkNode { int data; struct LinkNode* next; // Why there use `struct` type define LinkNode again? }; 

The line struct LinkNode* next; does not define a new type. It declares a member variable next of the (already existing) type LinkNode.

What threw you off here is probably the keyword struct, which, as you already figured out, is purely optional in this context. The reason why you are allowed to put struct here in the first place is a heritage from C. C distinguishes between tag names and type names. A declaration of the form struct Foo {}; in C only introduces a tag name Foo, but not a type name. This means that to instantiate an object of Foo in C you would need to write struct Foo f;, with the struct keyword there to turn the tag name into the corresponding type.

To get a proper type name in C, you'd have to use a typedef: typedef struct Foo FooType; which would then allow you to just write FooType f;. Since this distinction between tag names and type names proved to be not very useful in practice, C++ simply got rid of the distinction, allowing the simpler declaration notation you are familiar with.

4 Comments

As I understand it, C++ maintains the distinction, hence why elaborated type specifiers are possible, but it also injects tag names into the type name space too. Edit: searching briefly, I see this might be misremembered misinformation :-)
@underscore_d Although the wording of C++ may be different, I'm not sure if there is practical difference with types and tags having shared name space versus all tags implicitly having a type name.
@underscore_d C++ still has some machinery in there to support some of the weirder uses that are supported through C's tagging. See for instance the examples in class.name. However, it does not support all of C's use cases (in particular it bans redefining to an unrelated type via typedef), so it is a different system. Barring weird corner cases, just pretending tag types don't exist in C++ except for backwards compatibility with C is a very good approximation of truth in practice though.
@ComicSansMS, wow, what a good explanation, It solve my question about typedef keywork either. Very thanks. It help me a lot for a new learner.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.