Using an anonymous struct vs a named struct with typedef
Clash Royale CLAN TAG#URR8PPP
When should one of the following statements be used over the other?
typedef struct Foo
int a;
Bar;
and
typedef struct
int a;
Bar;
and use it like
Bar bar1 = 5;
I understand the second on is an anonymous struct but not sure when should one be used over the other.
c
add a comment |
When should one of the following statements be used over the other?
typedef struct Foo
int a;
Bar;
and
typedef struct
int a;
Bar;
and use it like
Bar bar1 = 5;
I understand the second on is an anonymous struct but not sure when should one be used over the other.
c
2
When you create a linked list, for example, you need to use the name of the struct inside the struct - in which case you have to use the first example. in other cases I don't think there is an advantage to the first over the second
– Asaf Rosemarin
Feb 18 at 18:00
Related: stackoverflow.com/q/54753213/6699433
– Broman
Feb 18 at 18:35
This is an almost exact duplicate of stackoverflow.com/questions/1110944/… but since both the question and the answers here are better I don't want to have this one closed. What's the appropriate action here? Flagging the other question (which is 10 years old!) as a duplicate of this one?
– Fabio Turati
Feb 19 at 11:43
add a comment |
When should one of the following statements be used over the other?
typedef struct Foo
int a;
Bar;
and
typedef struct
int a;
Bar;
and use it like
Bar bar1 = 5;
I understand the second on is an anonymous struct but not sure when should one be used over the other.
c
When should one of the following statements be used over the other?
typedef struct Foo
int a;
Bar;
and
typedef struct
int a;
Bar;
and use it like
Bar bar1 = 5;
I understand the second on is an anonymous struct but not sure when should one be used over the other.
c
c
asked Feb 18 at 17:54
JoeJoe
942
942
2
When you create a linked list, for example, you need to use the name of the struct inside the struct - in which case you have to use the first example. in other cases I don't think there is an advantage to the first over the second
– Asaf Rosemarin
Feb 18 at 18:00
Related: stackoverflow.com/q/54753213/6699433
– Broman
Feb 18 at 18:35
This is an almost exact duplicate of stackoverflow.com/questions/1110944/… but since both the question and the answers here are better I don't want to have this one closed. What's the appropriate action here? Flagging the other question (which is 10 years old!) as a duplicate of this one?
– Fabio Turati
Feb 19 at 11:43
add a comment |
2
When you create a linked list, for example, you need to use the name of the struct inside the struct - in which case you have to use the first example. in other cases I don't think there is an advantage to the first over the second
– Asaf Rosemarin
Feb 18 at 18:00
Related: stackoverflow.com/q/54753213/6699433
– Broman
Feb 18 at 18:35
This is an almost exact duplicate of stackoverflow.com/questions/1110944/… but since both the question and the answers here are better I don't want to have this one closed. What's the appropriate action here? Flagging the other question (which is 10 years old!) as a duplicate of this one?
– Fabio Turati
Feb 19 at 11:43
2
2
When you create a linked list, for example, you need to use the name of the struct inside the struct - in which case you have to use the first example. in other cases I don't think there is an advantage to the first over the second
– Asaf Rosemarin
Feb 18 at 18:00
When you create a linked list, for example, you need to use the name of the struct inside the struct - in which case you have to use the first example. in other cases I don't think there is an advantage to the first over the second
– Asaf Rosemarin
Feb 18 at 18:00
Related: stackoverflow.com/q/54753213/6699433
– Broman
Feb 18 at 18:35
Related: stackoverflow.com/q/54753213/6699433
– Broman
Feb 18 at 18:35
This is an almost exact duplicate of stackoverflow.com/questions/1110944/… but since both the question and the answers here are better I don't want to have this one closed. What's the appropriate action here? Flagging the other question (which is 10 years old!) as a duplicate of this one?
– Fabio Turati
Feb 19 at 11:43
This is an almost exact duplicate of stackoverflow.com/questions/1110944/… but since both the question and the answers here are better I don't want to have this one closed. What's the appropriate action here? Flagging the other question (which is 10 years old!) as a duplicate of this one?
– Fabio Turati
Feb 19 at 11:43
add a comment |
6 Answers
6
active
oldest
votes
They are pretty much equivalent. Actually, you can use the same name on both places. And you should. Use the same name unless you can come up with a good reason not to.
One situation where you want the non-anonymous is when you want pointers to an object of the same type, like in a linked list.
typedef struct Node
struct Node* next;
int data;
Node;
One alternative:
typedef struct Node Node;
struct Node
Node * next;
int data;
;
4
I would go further and say you should use the same for tag-name and typedef-name. Fewer things to keep in mind is better.
– Deduplicator
Feb 19 at 1:10
add a comment |
It doesn't really matter much. If you use the tagged form you can
have pointers to struct Foo
inside struct Foo
(AKA Bar)
typedef struct Foo
int a;
struct Foo *foop;
Bar;
but there's no way to do that with the second form
typedef struct
int a;
//Baz *p; not valid here since Baz isn't a typename yet
Baz;
Some codebases prefer not to use typedef
s at all and simply spell out struct Foo
with the struct keyword every time.
Also, with the first form, you can refer to the type either via the tag (struct Foo
) or with typedefs
(Bar
or any future/previous typedef
s (you can do typedef struct Foo PreviousTypedef;
before you provide the definition).
With the second form, on the other hand, you can only use the Baz
typedef
and possible future typedef
s (you can't forward-typedef
the struct since it doesn't have a tag).
(Note that typedef
doesn't really define types in C. The struct optional_tag /*...*/
part does. Rather, typedef
provides type aliases (so perhaps it should have been named typealias
).)
add a comment |
One time where the former is required is if you're making a linked list:
typedef struct list
int data;
struct list *next;
list;
The typedef list
is not visible inside of the struct definition, so you need to use the actual struct name to create a pointer to it.
If you don't have such a structure, you can use either one.
What you shouldn't do however is use a tag name that starts with an underscore, i.e.:
typedef struct _list
int data;
struct list *next;
list;
Because names starting with a underscore are reserved by the implementation.
2
It's more complcated, but never starting with an underscore nor using consecutive underscores is a good rule of thumb.
– Deduplicator
Feb 19 at 1:07
add a comment |
A lot of other people are focusing on the self referential aspect of this, but another reason to avoid doing this is that due to the lack of namespaces in C. In some circles it is standard practice to not typedef
structs to avoid struct
qualifier and instead refer to structs with the full specifier (eg void foo(struct Foo* foo_ptr)
). So if you wanted to maintain such a style, you wouldn't have the option to abuse anonymous structs, so this:
typedef struct
int a;
Bar;
Bar bar1 = 5;
should always instead be
struct Bar
int a;
;
struct Bar bar1 = 5;
otherwise you couldn't even compile bar1's instantiation with out typedef
ing away the struct
qualifier
1
What's the benefit? The vast majority of custom types are structs, not enums or unions. It's pretty clear that you're talking about a struct, without explicitly stating it.
– Alexander
Feb 19 at 3:39
1
@Alexander it isn't about being clear that something is a struct, its about maximizing use of the single namespace C gives you. A typedefd struct name can conflict with enums, unions, functions and structs, but if you don't typedef out the struct qualifier, structs can only conflict with other structs, greatly reducing the potential for namespace conflicts.
– opa
Feb 19 at 14:19
1
If your struct names conflict with functions, unions or enums, then your names suck. Structs should be nouns, functions should be verbs and verb phrases, thus they should never overlap. Enum names almost always imply they're enums, with words likeFooKind
,FooTypes
,FooIDs
, etc., and unions are pretty rare. You should never really use unions directly, anyway, so their names are usually some kind of_
prefixed private API. A union doesn't store its "active case", so you almost always have to use it as part of a struct that also stores an enum tag.
– Alexander
Feb 19 at 16:13
add a comment |
The term anonymous struct is already used for something else: in nested structs (or unions) that don't have a name at all and whose fields are referred to as if they were entries in the parent.
The actual question about when to use one or the other is that you have to use the first form if you want to add a pointer to its own type inside it like so:
typedef struct Foo struct Foo* Child; ... Foo;
However, what I would prefer is to do that with a typedef like so:
typedef struct Foo Foo;
struct Foo Foo* Child;;
add a comment |
When creating an opaque data type which is when the header only contains a forward declaration of the struct
and the actual definition of it's members is in the source file. Since you cannot forward declare a typedef
you'll have to give a struct
a name. Example:
Foo.h
typedef struct _Foo Foo;
Foo.c
struct _Foo
int a;
;
Also when you have a recursive data structure such as linked list which everyone else has mentioned.
1
Names beginning with underscore are reserved to the implementation; names beginning with underscore followed by an upper-case letter are even more reserved - they may well be macros. So be more careful with your examples!
– Toby Speight
Feb 19 at 11:04
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54752861%2fusing-an-anonymous-struct-vs-a-named-struct-with-typedef%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
They are pretty much equivalent. Actually, you can use the same name on both places. And you should. Use the same name unless you can come up with a good reason not to.
One situation where you want the non-anonymous is when you want pointers to an object of the same type, like in a linked list.
typedef struct Node
struct Node* next;
int data;
Node;
One alternative:
typedef struct Node Node;
struct Node
Node * next;
int data;
;
4
I would go further and say you should use the same for tag-name and typedef-name. Fewer things to keep in mind is better.
– Deduplicator
Feb 19 at 1:10
add a comment |
They are pretty much equivalent. Actually, you can use the same name on both places. And you should. Use the same name unless you can come up with a good reason not to.
One situation where you want the non-anonymous is when you want pointers to an object of the same type, like in a linked list.
typedef struct Node
struct Node* next;
int data;
Node;
One alternative:
typedef struct Node Node;
struct Node
Node * next;
int data;
;
4
I would go further and say you should use the same for tag-name and typedef-name. Fewer things to keep in mind is better.
– Deduplicator
Feb 19 at 1:10
add a comment |
They are pretty much equivalent. Actually, you can use the same name on both places. And you should. Use the same name unless you can come up with a good reason not to.
One situation where you want the non-anonymous is when you want pointers to an object of the same type, like in a linked list.
typedef struct Node
struct Node* next;
int data;
Node;
One alternative:
typedef struct Node Node;
struct Node
Node * next;
int data;
;
They are pretty much equivalent. Actually, you can use the same name on both places. And you should. Use the same name unless you can come up with a good reason not to.
One situation where you want the non-anonymous is when you want pointers to an object of the same type, like in a linked list.
typedef struct Node
struct Node* next;
int data;
Node;
One alternative:
typedef struct Node Node;
struct Node
Node * next;
int data;
;
edited Feb 19 at 12:18
answered Feb 18 at 18:02
BromanBroman
7,084112443
7,084112443
4
I would go further and say you should use the same for tag-name and typedef-name. Fewer things to keep in mind is better.
– Deduplicator
Feb 19 at 1:10
add a comment |
4
I would go further and say you should use the same for tag-name and typedef-name. Fewer things to keep in mind is better.
– Deduplicator
Feb 19 at 1:10
4
4
I would go further and say you should use the same for tag-name and typedef-name. Fewer things to keep in mind is better.
– Deduplicator
Feb 19 at 1:10
I would go further and say you should use the same for tag-name and typedef-name. Fewer things to keep in mind is better.
– Deduplicator
Feb 19 at 1:10
add a comment |
It doesn't really matter much. If you use the tagged form you can
have pointers to struct Foo
inside struct Foo
(AKA Bar)
typedef struct Foo
int a;
struct Foo *foop;
Bar;
but there's no way to do that with the second form
typedef struct
int a;
//Baz *p; not valid here since Baz isn't a typename yet
Baz;
Some codebases prefer not to use typedef
s at all and simply spell out struct Foo
with the struct keyword every time.
Also, with the first form, you can refer to the type either via the tag (struct Foo
) or with typedefs
(Bar
or any future/previous typedef
s (you can do typedef struct Foo PreviousTypedef;
before you provide the definition).
With the second form, on the other hand, you can only use the Baz
typedef
and possible future typedef
s (you can't forward-typedef
the struct since it doesn't have a tag).
(Note that typedef
doesn't really define types in C. The struct optional_tag /*...*/
part does. Rather, typedef
provides type aliases (so perhaps it should have been named typealias
).)
add a comment |
It doesn't really matter much. If you use the tagged form you can
have pointers to struct Foo
inside struct Foo
(AKA Bar)
typedef struct Foo
int a;
struct Foo *foop;
Bar;
but there's no way to do that with the second form
typedef struct
int a;
//Baz *p; not valid here since Baz isn't a typename yet
Baz;
Some codebases prefer not to use typedef
s at all and simply spell out struct Foo
with the struct keyword every time.
Also, with the first form, you can refer to the type either via the tag (struct Foo
) or with typedefs
(Bar
or any future/previous typedef
s (you can do typedef struct Foo PreviousTypedef;
before you provide the definition).
With the second form, on the other hand, you can only use the Baz
typedef
and possible future typedef
s (you can't forward-typedef
the struct since it doesn't have a tag).
(Note that typedef
doesn't really define types in C. The struct optional_tag /*...*/
part does. Rather, typedef
provides type aliases (so perhaps it should have been named typealias
).)
add a comment |
It doesn't really matter much. If you use the tagged form you can
have pointers to struct Foo
inside struct Foo
(AKA Bar)
typedef struct Foo
int a;
struct Foo *foop;
Bar;
but there's no way to do that with the second form
typedef struct
int a;
//Baz *p; not valid here since Baz isn't a typename yet
Baz;
Some codebases prefer not to use typedef
s at all and simply spell out struct Foo
with the struct keyword every time.
Also, with the first form, you can refer to the type either via the tag (struct Foo
) or with typedefs
(Bar
or any future/previous typedef
s (you can do typedef struct Foo PreviousTypedef;
before you provide the definition).
With the second form, on the other hand, you can only use the Baz
typedef
and possible future typedef
s (you can't forward-typedef
the struct since it doesn't have a tag).
(Note that typedef
doesn't really define types in C. The struct optional_tag /*...*/
part does. Rather, typedef
provides type aliases (so perhaps it should have been named typealias
).)
It doesn't really matter much. If you use the tagged form you can
have pointers to struct Foo
inside struct Foo
(AKA Bar)
typedef struct Foo
int a;
struct Foo *foop;
Bar;
but there's no way to do that with the second form
typedef struct
int a;
//Baz *p; not valid here since Baz isn't a typename yet
Baz;
Some codebases prefer not to use typedef
s at all and simply spell out struct Foo
with the struct keyword every time.
Also, with the first form, you can refer to the type either via the tag (struct Foo
) or with typedefs
(Bar
or any future/previous typedef
s (you can do typedef struct Foo PreviousTypedef;
before you provide the definition).
With the second form, on the other hand, you can only use the Baz
typedef
and possible future typedef
s (you can't forward-typedef
the struct since it doesn't have a tag).
(Note that typedef
doesn't really define types in C. The struct optional_tag /*...*/
part does. Rather, typedef
provides type aliases (so perhaps it should have been named typealias
).)
edited Feb 18 at 18:10
answered Feb 18 at 18:01
PSkocikPSkocik
34.3k65578
34.3k65578
add a comment |
add a comment |
One time where the former is required is if you're making a linked list:
typedef struct list
int data;
struct list *next;
list;
The typedef list
is not visible inside of the struct definition, so you need to use the actual struct name to create a pointer to it.
If you don't have such a structure, you can use either one.
What you shouldn't do however is use a tag name that starts with an underscore, i.e.:
typedef struct _list
int data;
struct list *next;
list;
Because names starting with a underscore are reserved by the implementation.
2
It's more complcated, but never starting with an underscore nor using consecutive underscores is a good rule of thumb.
– Deduplicator
Feb 19 at 1:07
add a comment |
One time where the former is required is if you're making a linked list:
typedef struct list
int data;
struct list *next;
list;
The typedef list
is not visible inside of the struct definition, so you need to use the actual struct name to create a pointer to it.
If you don't have such a structure, you can use either one.
What you shouldn't do however is use a tag name that starts with an underscore, i.e.:
typedef struct _list
int data;
struct list *next;
list;
Because names starting with a underscore are reserved by the implementation.
2
It's more complcated, but never starting with an underscore nor using consecutive underscores is a good rule of thumb.
– Deduplicator
Feb 19 at 1:07
add a comment |
One time where the former is required is if you're making a linked list:
typedef struct list
int data;
struct list *next;
list;
The typedef list
is not visible inside of the struct definition, so you need to use the actual struct name to create a pointer to it.
If you don't have such a structure, you can use either one.
What you shouldn't do however is use a tag name that starts with an underscore, i.e.:
typedef struct _list
int data;
struct list *next;
list;
Because names starting with a underscore are reserved by the implementation.
One time where the former is required is if you're making a linked list:
typedef struct list
int data;
struct list *next;
list;
The typedef list
is not visible inside of the struct definition, so you need to use the actual struct name to create a pointer to it.
If you don't have such a structure, you can use either one.
What you shouldn't do however is use a tag name that starts with an underscore, i.e.:
typedef struct _list
int data;
struct list *next;
list;
Because names starting with a underscore are reserved by the implementation.
edited Feb 18 at 20:24
answered Feb 18 at 18:01
dbushdbush
102k13106144
102k13106144
2
It's more complcated, but never starting with an underscore nor using consecutive underscores is a good rule of thumb.
– Deduplicator
Feb 19 at 1:07
add a comment |
2
It's more complcated, but never starting with an underscore nor using consecutive underscores is a good rule of thumb.
– Deduplicator
Feb 19 at 1:07
2
2
It's more complcated, but never starting with an underscore nor using consecutive underscores is a good rule of thumb.
– Deduplicator
Feb 19 at 1:07
It's more complcated, but never starting with an underscore nor using consecutive underscores is a good rule of thumb.
– Deduplicator
Feb 19 at 1:07
add a comment |
A lot of other people are focusing on the self referential aspect of this, but another reason to avoid doing this is that due to the lack of namespaces in C. In some circles it is standard practice to not typedef
structs to avoid struct
qualifier and instead refer to structs with the full specifier (eg void foo(struct Foo* foo_ptr)
). So if you wanted to maintain such a style, you wouldn't have the option to abuse anonymous structs, so this:
typedef struct
int a;
Bar;
Bar bar1 = 5;
should always instead be
struct Bar
int a;
;
struct Bar bar1 = 5;
otherwise you couldn't even compile bar1's instantiation with out typedef
ing away the struct
qualifier
1
What's the benefit? The vast majority of custom types are structs, not enums or unions. It's pretty clear that you're talking about a struct, without explicitly stating it.
– Alexander
Feb 19 at 3:39
1
@Alexander it isn't about being clear that something is a struct, its about maximizing use of the single namespace C gives you. A typedefd struct name can conflict with enums, unions, functions and structs, but if you don't typedef out the struct qualifier, structs can only conflict with other structs, greatly reducing the potential for namespace conflicts.
– opa
Feb 19 at 14:19
1
If your struct names conflict with functions, unions or enums, then your names suck. Structs should be nouns, functions should be verbs and verb phrases, thus they should never overlap. Enum names almost always imply they're enums, with words likeFooKind
,FooTypes
,FooIDs
, etc., and unions are pretty rare. You should never really use unions directly, anyway, so their names are usually some kind of_
prefixed private API. A union doesn't store its "active case", so you almost always have to use it as part of a struct that also stores an enum tag.
– Alexander
Feb 19 at 16:13
add a comment |
A lot of other people are focusing on the self referential aspect of this, but another reason to avoid doing this is that due to the lack of namespaces in C. In some circles it is standard practice to not typedef
structs to avoid struct
qualifier and instead refer to structs with the full specifier (eg void foo(struct Foo* foo_ptr)
). So if you wanted to maintain such a style, you wouldn't have the option to abuse anonymous structs, so this:
typedef struct
int a;
Bar;
Bar bar1 = 5;
should always instead be
struct Bar
int a;
;
struct Bar bar1 = 5;
otherwise you couldn't even compile bar1's instantiation with out typedef
ing away the struct
qualifier
1
What's the benefit? The vast majority of custom types are structs, not enums or unions. It's pretty clear that you're talking about a struct, without explicitly stating it.
– Alexander
Feb 19 at 3:39
1
@Alexander it isn't about being clear that something is a struct, its about maximizing use of the single namespace C gives you. A typedefd struct name can conflict with enums, unions, functions and structs, but if you don't typedef out the struct qualifier, structs can only conflict with other structs, greatly reducing the potential for namespace conflicts.
– opa
Feb 19 at 14:19
1
If your struct names conflict with functions, unions or enums, then your names suck. Structs should be nouns, functions should be verbs and verb phrases, thus they should never overlap. Enum names almost always imply they're enums, with words likeFooKind
,FooTypes
,FooIDs
, etc., and unions are pretty rare. You should never really use unions directly, anyway, so their names are usually some kind of_
prefixed private API. A union doesn't store its "active case", so you almost always have to use it as part of a struct that also stores an enum tag.
– Alexander
Feb 19 at 16:13
add a comment |
A lot of other people are focusing on the self referential aspect of this, but another reason to avoid doing this is that due to the lack of namespaces in C. In some circles it is standard practice to not typedef
structs to avoid struct
qualifier and instead refer to structs with the full specifier (eg void foo(struct Foo* foo_ptr)
). So if you wanted to maintain such a style, you wouldn't have the option to abuse anonymous structs, so this:
typedef struct
int a;
Bar;
Bar bar1 = 5;
should always instead be
struct Bar
int a;
;
struct Bar bar1 = 5;
otherwise you couldn't even compile bar1's instantiation with out typedef
ing away the struct
qualifier
A lot of other people are focusing on the self referential aspect of this, but another reason to avoid doing this is that due to the lack of namespaces in C. In some circles it is standard practice to not typedef
structs to avoid struct
qualifier and instead refer to structs with the full specifier (eg void foo(struct Foo* foo_ptr)
). So if you wanted to maintain such a style, you wouldn't have the option to abuse anonymous structs, so this:
typedef struct
int a;
Bar;
Bar bar1 = 5;
should always instead be
struct Bar
int a;
;
struct Bar bar1 = 5;
otherwise you couldn't even compile bar1's instantiation with out typedef
ing away the struct
qualifier
answered Feb 18 at 19:58
opaopa
1,5971526
1,5971526
1
What's the benefit? The vast majority of custom types are structs, not enums or unions. It's pretty clear that you're talking about a struct, without explicitly stating it.
– Alexander
Feb 19 at 3:39
1
@Alexander it isn't about being clear that something is a struct, its about maximizing use of the single namespace C gives you. A typedefd struct name can conflict with enums, unions, functions and structs, but if you don't typedef out the struct qualifier, structs can only conflict with other structs, greatly reducing the potential for namespace conflicts.
– opa
Feb 19 at 14:19
1
If your struct names conflict with functions, unions or enums, then your names suck. Structs should be nouns, functions should be verbs and verb phrases, thus they should never overlap. Enum names almost always imply they're enums, with words likeFooKind
,FooTypes
,FooIDs
, etc., and unions are pretty rare. You should never really use unions directly, anyway, so their names are usually some kind of_
prefixed private API. A union doesn't store its "active case", so you almost always have to use it as part of a struct that also stores an enum tag.
– Alexander
Feb 19 at 16:13
add a comment |
1
What's the benefit? The vast majority of custom types are structs, not enums or unions. It's pretty clear that you're talking about a struct, without explicitly stating it.
– Alexander
Feb 19 at 3:39
1
@Alexander it isn't about being clear that something is a struct, its about maximizing use of the single namespace C gives you. A typedefd struct name can conflict with enums, unions, functions and structs, but if you don't typedef out the struct qualifier, structs can only conflict with other structs, greatly reducing the potential for namespace conflicts.
– opa
Feb 19 at 14:19
1
If your struct names conflict with functions, unions or enums, then your names suck. Structs should be nouns, functions should be verbs and verb phrases, thus they should never overlap. Enum names almost always imply they're enums, with words likeFooKind
,FooTypes
,FooIDs
, etc., and unions are pretty rare. You should never really use unions directly, anyway, so their names are usually some kind of_
prefixed private API. A union doesn't store its "active case", so you almost always have to use it as part of a struct that also stores an enum tag.
– Alexander
Feb 19 at 16:13
1
1
What's the benefit? The vast majority of custom types are structs, not enums or unions. It's pretty clear that you're talking about a struct, without explicitly stating it.
– Alexander
Feb 19 at 3:39
What's the benefit? The vast majority of custom types are structs, not enums or unions. It's pretty clear that you're talking about a struct, without explicitly stating it.
– Alexander
Feb 19 at 3:39
1
1
@Alexander it isn't about being clear that something is a struct, its about maximizing use of the single namespace C gives you. A typedefd struct name can conflict with enums, unions, functions and structs, but if you don't typedef out the struct qualifier, structs can only conflict with other structs, greatly reducing the potential for namespace conflicts.
– opa
Feb 19 at 14:19
@Alexander it isn't about being clear that something is a struct, its about maximizing use of the single namespace C gives you. A typedefd struct name can conflict with enums, unions, functions and structs, but if you don't typedef out the struct qualifier, structs can only conflict with other structs, greatly reducing the potential for namespace conflicts.
– opa
Feb 19 at 14:19
1
1
If your struct names conflict with functions, unions or enums, then your names suck. Structs should be nouns, functions should be verbs and verb phrases, thus they should never overlap. Enum names almost always imply they're enums, with words like
FooKind
, FooTypes
, FooIDs
, etc., and unions are pretty rare. You should never really use unions directly, anyway, so their names are usually some kind of _
prefixed private API. A union doesn't store its "active case", so you almost always have to use it as part of a struct that also stores an enum tag.– Alexander
Feb 19 at 16:13
If your struct names conflict with functions, unions or enums, then your names suck. Structs should be nouns, functions should be verbs and verb phrases, thus they should never overlap. Enum names almost always imply they're enums, with words like
FooKind
, FooTypes
, FooIDs
, etc., and unions are pretty rare. You should never really use unions directly, anyway, so their names are usually some kind of _
prefixed private API. A union doesn't store its "active case", so you almost always have to use it as part of a struct that also stores an enum tag.– Alexander
Feb 19 at 16:13
add a comment |
The term anonymous struct is already used for something else: in nested structs (or unions) that don't have a name at all and whose fields are referred to as if they were entries in the parent.
The actual question about when to use one or the other is that you have to use the first form if you want to add a pointer to its own type inside it like so:
typedef struct Foo struct Foo* Child; ... Foo;
However, what I would prefer is to do that with a typedef like so:
typedef struct Foo Foo;
struct Foo Foo* Child;;
add a comment |
The term anonymous struct is already used for something else: in nested structs (or unions) that don't have a name at all and whose fields are referred to as if they were entries in the parent.
The actual question about when to use one or the other is that you have to use the first form if you want to add a pointer to its own type inside it like so:
typedef struct Foo struct Foo* Child; ... Foo;
However, what I would prefer is to do that with a typedef like so:
typedef struct Foo Foo;
struct Foo Foo* Child;;
add a comment |
The term anonymous struct is already used for something else: in nested structs (or unions) that don't have a name at all and whose fields are referred to as if they were entries in the parent.
The actual question about when to use one or the other is that you have to use the first form if you want to add a pointer to its own type inside it like so:
typedef struct Foo struct Foo* Child; ... Foo;
However, what I would prefer is to do that with a typedef like so:
typedef struct Foo Foo;
struct Foo Foo* Child;;
The term anonymous struct is already used for something else: in nested structs (or unions) that don't have a name at all and whose fields are referred to as if they were entries in the parent.
The actual question about when to use one or the other is that you have to use the first form if you want to add a pointer to its own type inside it like so:
typedef struct Foo struct Foo* Child; ... Foo;
However, what I would prefer is to do that with a typedef like so:
typedef struct Foo Foo;
struct Foo Foo* Child;;
edited Feb 19 at 11:45
Fabio Turati
2,63452241
2,63452241
answered Feb 18 at 18:02
Bernd ElkemannBernd Elkemann
20.9k43055
20.9k43055
add a comment |
add a comment |
When creating an opaque data type which is when the header only contains a forward declaration of the struct
and the actual definition of it's members is in the source file. Since you cannot forward declare a typedef
you'll have to give a struct
a name. Example:
Foo.h
typedef struct _Foo Foo;
Foo.c
struct _Foo
int a;
;
Also when you have a recursive data structure such as linked list which everyone else has mentioned.
1
Names beginning with underscore are reserved to the implementation; names beginning with underscore followed by an upper-case letter are even more reserved - they may well be macros. So be more careful with your examples!
– Toby Speight
Feb 19 at 11:04
add a comment |
When creating an opaque data type which is when the header only contains a forward declaration of the struct
and the actual definition of it's members is in the source file. Since you cannot forward declare a typedef
you'll have to give a struct
a name. Example:
Foo.h
typedef struct _Foo Foo;
Foo.c
struct _Foo
int a;
;
Also when you have a recursive data structure such as linked list which everyone else has mentioned.
1
Names beginning with underscore are reserved to the implementation; names beginning with underscore followed by an upper-case letter are even more reserved - they may well be macros. So be more careful with your examples!
– Toby Speight
Feb 19 at 11:04
add a comment |
When creating an opaque data type which is when the header only contains a forward declaration of the struct
and the actual definition of it's members is in the source file. Since you cannot forward declare a typedef
you'll have to give a struct
a name. Example:
Foo.h
typedef struct _Foo Foo;
Foo.c
struct _Foo
int a;
;
Also when you have a recursive data structure such as linked list which everyone else has mentioned.
When creating an opaque data type which is when the header only contains a forward declaration of the struct
and the actual definition of it's members is in the source file. Since you cannot forward declare a typedef
you'll have to give a struct
a name. Example:
Foo.h
typedef struct _Foo Foo;
Foo.c
struct _Foo
int a;
;
Also when you have a recursive data structure such as linked list which everyone else has mentioned.
answered Feb 18 at 18:11
r3mus n0xr3mus n0x
2,7431323
2,7431323
1
Names beginning with underscore are reserved to the implementation; names beginning with underscore followed by an upper-case letter are even more reserved - they may well be macros. So be more careful with your examples!
– Toby Speight
Feb 19 at 11:04
add a comment |
1
Names beginning with underscore are reserved to the implementation; names beginning with underscore followed by an upper-case letter are even more reserved - they may well be macros. So be more careful with your examples!
– Toby Speight
Feb 19 at 11:04
1
1
Names beginning with underscore are reserved to the implementation; names beginning with underscore followed by an upper-case letter are even more reserved - they may well be macros. So be more careful with your examples!
– Toby Speight
Feb 19 at 11:04
Names beginning with underscore are reserved to the implementation; names beginning with underscore followed by an upper-case letter are even more reserved - they may well be macros. So be more careful with your examples!
– Toby Speight
Feb 19 at 11:04
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54752861%2fusing-an-anonymous-struct-vs-a-named-struct-with-typedef%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
When you create a linked list, for example, you need to use the name of the struct inside the struct - in which case you have to use the first example. in other cases I don't think there is an advantage to the first over the second
– Asaf Rosemarin
Feb 18 at 18:00
Related: stackoverflow.com/q/54753213/6699433
– Broman
Feb 18 at 18:35
This is an almost exact duplicate of stackoverflow.com/questions/1110944/… but since both the question and the answers here are better I don't want to have this one closed. What's the appropriate action here? Flagging the other question (which is 10 years old!) as a duplicate of this one?
– Fabio Turati
Feb 19 at 11:43