Izzo
Izzo

Reputation: 4948

Why must the 'struct' keyword precede struct instances in C?

Let's say I define a struct in C. If I declare an instance of that struct, it's necessary that I include the 'struct' keyword in front of it.

// Define struct
struct Book {
   char title[50];
   char author[50];
   char subject[100];
   int book_id;
};

// Instantiate struct
int main()
{
    struct Book myBook;
}

My question: why is it necessary for the struct keyword to precede any instantiation of the struct? It seems like the compiler would have plenty of information to deduct that 'Book' is a struct.

I realize you can get around this by using a typedef, but that really just seems like boiler plate code for something the compiler should already know.

Upvotes: 3

Views: 403

Answers (2)

Petr Skocik
Petr Skocik

Reputation: 60163

With the current arrangement, you could have both struct Book and a global/local symbol named Book, which doesn't need to be related to struct Book. struct stat existing alongside a function named stat is a nice example this feature being used in POSIX.

Clearly, you could automate the typedefing as C++ has done (and thereby lose the possibility of having a perhaps unrelated Book and struct Book in the same scope), but I guess that not automating it makes the grammar perhaps neater, because then if you don't use typedefs at all, you've got a basically context-free grammar, whereas with typedefs (explicit or implicit) a context of currently valid typedefed types has to be maintained by the parser.


Personally, I prefer automated typedefing to the possibility of having a global scope coexist with a struct tag of the same name, and so I do:

#define Struct(Nm,...) typedef struct Nm Nm; struct Nm __VA_ARGS__
#define Union(Nm,...) typedef union Nm Nm; union Nm __VA_ARGS__
#define Enum(Nm,...) enum Nm __VA_ARGS__; typedef enum Nm Nm

Struct(Book,{
   char title[50];
   char author[50];
   char subject[100];
   int book_id;
});

(You may want to use it alongside a naming convention that lets you know you're dealing with a struct/union/enum (e.g., _s as in book_s)).

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 311156

Due to using the keywords struct, union and enum names for these types can form their own namespace that will not conflict with names of other entities.

For example

#include <stdio.h>

int main(void) 
{
    struct Book 
    {
        const char *Book;
    } Book = { "The first favorite book" };

    struct Book otherBook = { .Book = "The second favorite book" };

    puts( Book.Book );
    puts( otherBook.Book );

    return 0;
}

Upvotes: 1

Related Questions