2

What does it mean when the name at the beginning of the struct and the one at the end of the struct are different? For example:

struct book{
   char title[50];
   int year;
}boo;

or for example

typedef struct book{
    char title[50];
    int year;
}boo;
  • 1
    Possible duplicate of [C : typedef struct name {...}; VS typedef struct{...} name;](https://stackoverflow.com/questions/17720223/c-typedef-struct-name-vs-typedef-struct-name) – Morten Jensen Aug 12 '19 at 10:10
  • [struct name & alias](https://stackoverflow.com/questions/10385720/using-a-struct-in-a-header-file-unknown-type-error/10386888#10386888) – Agnius Vasiliauskas Aug 12 '19 at 10:11
  • Why should they be same? – Gerhardh Aug 12 '19 at 10:21
  • Ah I almost missed the [c] tag, generally you don't see the trailing alias in c++ because structs and classes are basically self aliasing and you do not use 'struct' before declarations. so you can just do `struct book{ char title[50]; int year; } ;` followed by `book bookobj { "A lazy title", 1955 } ; ` – Max Power Jul 07 '22 at 22:38

4 Answers4

3

This example

struct book{
   char title[50];
   int year;
}boo;

Creates a variable called boo that has the type struct book.

The other example:

typedef struct book{
    char title[50];
    int year;
}boo;

Defines boo to be the same type as struct book, an alias sort-of.

Morten Jensen
  • 5,818
  • 3
  • 43
  • 55
  • 1
    Why do you say a `typedef` defines an “alias sort-of.” It defines an alias actually, not sort-of. – Eric Postpischil Aug 12 '19 at 11:50
  • @EricPostpischil because English isn't my native language so it snuck in and added ambiguity I guess? I agree that it's an alias and that the "sort-of" can be left out. – Morten Jensen Jul 25 '21 at 21:05
3

In the 1st case you define a struct and right away create a variable of its type.

struct book{
    char title[50];
    int year;
}boo; // <== boo is already a variable, you can start using it; boo.year = 2019;

In the second example you make a typedef saying that the 'boo' declaration is now the same as your struct so you can create variables using that 'boo' afterwards. In this case no variable is created at the time of the struct declaration.

typedef struct book{
    char title[50];
    int year;
}boo;

boo a, b; // <== here you create variables
viktor
  • 53
  • 7
3

struct book is the type name (like int or double). The type is being defined by the stuff between the curly braces - { char title[50]; int year; }. In the first snippet, boo is being declared as an object (variable) of type struct book.

C allows you to both define the struct type and declare objects of that type in the same declaration. It may make sense to see the two operations broken up:

struct book { char title[50]; int year; }; // creates the *type* "struct book"
struct book boo;                           // declares a *variable* of type "struct book"

The typedef facility allows you to create synonyms or aliases for a type - in this case, typedef struct book { char title[50]; int year; } boo; creates boo as a synonym for struct book. You can then create objects as

boo b1; // b1 is type boo, which is a synonym for struct book.

Again, it may help to split things up:

struct book { char title[50]; int year; }; // creates the type "struct book"
typedef struct book boo;                   // makes boo an alias for type "struct book"

In struct book, book is the tag name for the struct type - it's what allows you to refer to that type after you've defined it, like

struct book b2;

void some_function( struct book b );

etc.

If you write something like

struct { char title[50]; int year; } boo;

then only boo can have that type - you can't declare other variables of that same type, because there's no way to refer to it anymore. Even if you repeat the type:

 struct { char title[50]; int year; } boo;
 struct { char title[50]; int year; } b2;

boo and b2 technically have different types, even though the type implementations are identical.

Now, if you use the typedef facility, you can omit the tag name:

typedef struct { char title[50]; int year } boo;

because now you refer to that type with the typedef name boo:

boo b2;

void some_function( boo b );
John Bode
  • 119,563
  • 19
  • 122
  • 198
0

When an identifier (a name) appears after struct, it is called a tag and the combined struct and identifier name a type. Quite simply, struct book is a type; its name is struct book.

When an identifier appears after the braces of a structure declaration, it is a separate name—it does not have an immediate connection with the structure. Its role depends on the larger declaration it is in. To see this, consider that one form of a declaration is “type name ;”. For example, we can have:

int a;
char b;
struct foo c;
struct bar { float x, y, z; } d;

In each of these, a, b, c, and d is an identifier for an object being declared, and the text preceding it is a type name. struct foo and struct bar { float x, y, z } are merely type names that are complicated instead of being single words. When declaring an identifier, we can use any name we want (following the usual rules about which characters are used and about reserved names and such).

We can also have various modifiers before the type name, such as:

extern int a;
static char b;
const struct foo c;
typedef struct bar { float x, y, z; } d;

The first three above also declare objects. In the fourth, typedef is special. It says “This is not declaring an object; it is making a new name for a type.” The fourth declaration says “d” is a new name for struct bar.

It is common to use typedef to make an alias for a struct that has the same name as the structure tag, as in:

typedef struct bar { float x, y, z; } bar;

However, there is no requirement for this in C. The name of the structure and any aliases for its type are unrelated, unless a programmer writes a typedef making them the same. (In C++, this is done automatically; declaring a struct bar creates a type named bar. In C, structure tags are in a different name space than type names.)

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312