Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the syntactically proper way to declare a C struct?

Tags:

c

syntax

struct

I've seen C structs declared several different ways before. Why is that and what, if anything, does each do different?

For example:

struct foo {   short a;   int b;   float c; };  typedef struct {   short d;   int e;   float f; } bar;  typedef struct _baz {   short a;   int b;   float c; } baz;  int main (int argc, char const *argv[]) {   struct foo a;   bar b;   baz c;    return 0; } 
like image 675
Mark Sands Avatar asked Jan 15 '11 08:01

Mark Sands


People also ask

How do you declare a struct in C?

The general syntax for a struct declaration in C is: struct tag_name { type member1; type member2; /* declare as many members as desired, but the entire structure size must be known to the compiler. */ }; Here tag_name is optional in some contexts.

What is the declaration of the struct?

A "structure declaration" names a type and specifies a sequence of variable values (called "members" or "fields" of the structure) that can have different types. An optional identifier, called a "tag," gives the name of the structure type and can be used in subsequent references to the structure type.

Where should I define struct in C?

If the struct definition is needed from multiple . c files then it should go in the header, otherwise it doesn't have to. @M.M It is only needed in one . c file.

Where should struct be declared?

Private structures for that file should go in the . c file, with a declaration in the . h file if they are used by any functions in the . h .


2 Answers

Well, the obvious difference is demonstrated in your main:

struct foo a; bar b; baz c; 

The first declaration is of an un-typedefed struct and needs the struct keyword to use. The second is of a typedefed anonymous struct, and so we use the typedef name. The third combines both the first and the second: your example uses baz (which is conveniently short) but could just as easily use struct _baz to the same effect.

Update: larsmans' answer mentions a more common case where you have to use at least struct x { } to make a linked list. The second case wouldn't be possible here (unless you abandon sanity and use a void * instead) because the struct is anonymous, and the typedef doesn't happen until the struct is defined, giving you no way to make a (type-safe) pointer to the struct type itself. The first version works fine for this use, but the third is generally preferred in my experience. Give him some rep for that.

A more subtle difference is in namespace placement. In C, struct tags are placed in a separate namespace from other names, but typedef names aren't. So the following is legal:

struct test {   // contents };  struct test *test() {   // contents } 

But the following is not, because it would be ambiguous what the name test is:

typedef struct {   // contents } test;  test *test() {   // contents } 

typedef makes the name shorter (always a plus), but it puts it in the same namespace as your variables and functions. Usually this isn't an issue, but it is a subtle difference beyond the simple shortening.

like image 54
Chris Lutz Avatar answered Oct 13 '22 07:10

Chris Lutz


It's largely a matter of personal preference. I like to give new types a name starting with a capital letter and omit the struct, so I usually write typedef struct { ... } Foo. That means I cannot then write struct Foo.

The exception is when a struct contains a pointer to its own type, e.g.

typedef struct Node {     // ...     struct Node *next; } Node; 

In this case you need to also declare the struct Node type, since the typedef is not in scope within the struct definition. Note that both names may be the same (I'm not sure where the underscore convention originated, but I guess older C compilers couldn't handle typedef struct X X;).

like image 30
Fred Foo Avatar answered Oct 13 '22 06:10

Fred Foo