tags:

views:

16155

answers:

8

I have seen many programs consisting of structures like the one below

typedef struct 
{
 int i;
 char k;
} elem;
elem user;

I have seen this many times. Why is it needed so often? Any specific reason or applicable area?

+13  A: 

Using a typedef avoids having to write struct every time you declare a variable of that type:

struct elem
{
 int i;
 char k;
};
elem user; // compile error!
struct elem user; // this is correct
Greg Hewgill
ok we are not having that problem in C++.So why dont anybody remove that glitch from the C's compiler and make it the same as in C++.ok C++ is having some different application areas and so it is having the advanced features.but can we not inherit some of them in C without changing the original C?
Manoj Doubts
Manoj, the tag name ("struct foo") is necessary when you need to define a struct that references itself. e.g. the "next" pointer in a linked list. More to the point, the compiler implements the standard, and that's what the standard says to do.
Michael Carman
It's not a glitch in the C compiler, it's part of the design. They changed that for C++, which I think makes things easier, but that doesn't mean C's behavior is wrong.
Herms
+28  A: 

As Greg Hewgill said, the typedef means you no longer have to write struct all over the place. That not only saves keystrokes, it also can make the code cleaner since it provides a smidgen more abstraction.

Stuff like

typedef struct {
  int x, y;
} Point;

Point point_new(int x, int y)
{
  Point a;
  a.x = x;
  a.y = y;
  return a;
}

becomes cleaner when you don't need to see the "struct" keyword all over the place, it looks more as if there really is a type called "Point" in your language. Which, after the typedef, is the case I guess.

Also note that while your example (and mine) omitted naming the struct itself, that case is also useful for when you want to provide an opaque type. Then you'd have code like this in the header, for instance:

typedef struct _Point Point;

Point * point_new(int x, int y);

and then provide the struct declaration in the implementation file:

struct _Point
{
  int x, y;
}

Point * point_new(int x, int y)
{
  Point *p;
  if((p = malloc(sizeof *p)) != NULL)
  {
    p->x = x;
    p->y = y;
  }
  return p;
}

In this latter case, you cannot return the Point by value, since its declaration is hidden from users of the header file. This is a technique used widely in GTK+, for instance.

unwind
+1  A: 

the name you (optionally) give the struct is called the tag name and, as has been noted, is not a type in itself. To get to the type requires the struct prefix.

GTK+ aside, I'm not sure the tagname is used anything like as commonly as a typedef to the struct type, so in C++ that is recognised and you can omit the struct keyword and use the tagname as the type name too:


    struct MyStruct
    {
      int i;
    };

    // The following is legal in C++:
    MyStruct obj;
    obj.i = 7;

Phil Nash
+11  A: 

From an old article by Dan Saks (http://www.ddj.com/cpp/184403396?pgno=3):


The C language rules for naming structs are a little eccentric, but they're pretty harmless. However, when extended to classes in C++, those same rules open little cracks for bugs to crawl through.

In C, the name s appearing in

struct s
    {
    ...
    };

is a tag. A tag name is not a type name. Given the definition above, declarations such as

s x;    /* error in C */
s *p;   /* error in C */

are errors in C. You must write them as

struct s x;     /* OK */
struct s *p;    /* OK */

The names of unions and enumerations are also tags rather than types.

In C, tags are distinct from all other names (for functions, types, variables, and enumeration constants). C compilers maintain tags in a symbol table that's conceptually if not physically separate from the table that holds all other names. Thus, it is possible for a C program to have both a tag and an another name with the same spelling in the same scope. For example,

struct s s;

is a valid declaration which declares variable s of type struct s. It may not be good practice, but C compilers must accept it. I have never seen a rationale for why C was designed this way. I have always thought it was a mistake, but there it is.

Many programmers (including yours truly) prefer to think of struct names as type names, so they define an alias for the tag using a typedef. For example, defining

struct s
    {
    ...
    };
typedef struct s S;

lets you use S in place of struct s, as in

S x;
S *p;

A program cannot use S as the name of both a type and a variable (or function or enumeration constant):

S S;    // error

This is good.

The tag name in a struct, union, or enum definition is optional. Many programmers fold the struct definition into the typedef and dispense with the tag altogether, as in:

typedef struct
    {
    ...
    } S;


The linked article also has a discussion about how the C++ behavior of not requireing a typedef can cause subtle name hiding problems. To prevent these problems, it's a good idea to typedef your classes and structs in C++, too, even though at first glance it appears to be unnecessary. In C++, with the typedef the name hiding become an error that the compiler tells you about rather than a hidden source of potential problems.

Michael Burr
A: 

You just answered your own question

PhirePhly
ya i got the answer from some one on the stackoverflow and i got this doubt abt the c and c++ advancements.so i posted it here.its a daughter question from that answer
Manoj Doubts
A: 

One other good reason to always typedef enums and structs results from this problem I have encountered with the Freescale Codewarrior compiler suite:

  enum EnumDef
  {
    FIRST_ITEM,
    SECOND_ITEM
  };

  struct StructDef
  {
    enum EnuumDef MyEnum;
    unsigned int MyVar;
  } MyStruct;

Notice the typo in EnumDef in the struct (Enu**u**mDef)? This compiles without error (or warning) and is (depending on the literal interpretation of the C Standard) correct. The problem is that I just created an new (empty) enumeration definition within my struct. I am not (as intended) using the previous definition EnumDef.

With a typdef similar kind of typos would have resulted in a compiler errors for using an unknown type:

  typedef 
  {
    FIRST_ITEM,
    SECOND_ITEM
  } EnumDef;

  typedef struct
  {
    EnuumDef MyEnum; /* compiler error (unknown type) */
    unsigned int MyVar;
  } StructDef;
  StrructDef MyStruct; /* compiler error (unknown type) */

I would advocate ALWAYS typedef'ing structs and enumerations.

Not only to save some typing (no pun intended ;)), but because it is safer.

cschol
A: 

At all, in C language, struct/union/enum are macro instruction processed by the C language preprocessor (do not mistake with the preprocessor that treat "#include" and other)

so :

struct a
{
   int i;
};

struct b
{
   struct a;
   int i;
   int j;
};

struct b is expended as something like this :

struct b
{
    struct a
    {
        int i;
    };
    int i;
    int j;
}

and so, at compile time it evolve on stack as something like: b: int ai int i int j

that also why it's dificult to have selfreferent structs, C preprocessor round in a déclaration loop that can't terminate.

typedef are type specifier, that means only C compiler process it and it can do like he want for optimise assembler code implementation. It also dont expend member of type par stupidly like préprocessor do with structs but use more complex reference construction algorithm, so construction like :

typedef struct a A; //anticipated declaration for member declaration

typedef struct a //Implemented declaration
{
    A* b; // member declaration
}A;

is permited and fully functional. This implementation give also access to compilator type conversion and remove some bugging effects when execution thread leave the application field of initialisation functions.

This mean that in C typedefs are more near as C++ class than lonely structs.

doccpu
A: 

Use of typedef in C++ makes quite a bit of sense. It can almost be necessary when dealing with templates that require multiple and/or variable parameters. The typedef helps keep the naming straight.

Not so in the C programming language. The use of typedef most often serves no purpose but to obfuscate the data structure usage. Since only { struct (6), enum (4), union (5) } number of keystrokes are used to declare a data type there is almost no use for the aliasing of the struct. Is that data type a union or a struct? Using the straight forward non-typdefed declaration lets you know right away what type it is.

Notice how Linux is written with strict avoidance of this aliasing nonsense typedef brings. The result is a minimalist and clean style.

natersoz
Clean would be not repeating `struct`everywhere... Typedef's make new types. What do you use? Types. We don't *care* if it's a struct, union, or enum, that's why we typedef it.
GMan