[comp.lang.c] structure typedefs

unhd (Roger Gonzalez ) (03/28/90)

Could someone kindly explain to me the difference between

typedef struct  foo {				typedef struct  {
    ..						    ..
};				and		}   foo;

struct foo  bar;				foo bar;


In some situations, it doesn't make any difference at all.  In others, most
notably when you have a pointer to the same type (i.e. linked list stuff)

typedef struct	foo {
    ..
    struct foo *next;
};

struct foo  bar;

I seem to recall even seeing this:

typedef struct  foo {
    ..
    struct foo *next;
} foo;

foo bar;

Which looks to me like it should cause an error.  Please enlighten me as to
the subtleties of this.  I'm not a novice C programmer, and I've been using
structures for years, and I know how to make them work, but I've never really
understood exactly what was going on internally.  Email if possible; I don't
read this group often.

-Roger

-- 
UUCP:   ..!uunet!unhd!rg      | USPS: Marine Systems Engineering Laboratory
BITNET: r_gonzalez at unhh    |       University of New Hampshire
PHONE:  (603) 862-4600        |       Marine Programs Building
FAX:    (603) 862-4399        |       Durham, NH  03824-3525

goudreau@larrybud.rtp.dg.com (Bob Goudreau) (03/30/90)

In article <1990Mar28.150755.6803@uunet!unhd>, rg@uunet!unhd (Roger
Gonzalez ) writes:
> 
> I seem to recall even seeing this:
> 
> typedef struct  foo {
>     ..
>     struct foo *next;
> } foo;
> 
> foo bar;
> 
> Which looks to me like it should cause an error.  Please enlighten me as to
> the subtleties of this.  I'm not a novice C programmer, and I've been using
> structures for years, and I know how to make them work, but I've never really
> understood exactly what was going on internally.  Email if possible; I don't
> read this group often.

There's nothing wrong with it; it's perfectly legal C.  The thing to
remember is that typedef names and structure names basically live in
two different namespaces.  There is no potential for ambiguity because
structure names must always be preceeded by the word "struct" and
typedef names can *never* be preceded by "struct".  So, to continue
your example, the following two variables have the same underlying
type:

	foo bar;
	struct foo bletch;

Of course, whether naming structs and types in this manner is good
programming practice is another question entirely.  The coding
standards for the project that I work on require that we always
create a typedef for any structs we invent.  Whenever possible (which
is most of the time), the struct itself has no self-references and
can thus be unnamed:

	typedef struct

	{
	a_type	a;
	b_type	b;

	}	foo_bar_type;


Only when there is need for self-reference does the structure get a
name, and to avoid confusion that name is produced by replacing the
"_type" in the typedef name with "_tag":

	typedef struct foo_whiz_tag

	{
	a_type			a;
	b_type			b;
	struct foo_whiz_tag *	next;

	}	foo_whiz_type;

------------------------------------------------------------------------
Bob Goudreau				+1 919 248 6231
Data General Corporation
62 Alexander Drive			goudreau@dg-rtp.dg.com
Research Triangle Park, NC  27709	...!mcnc!rti!xyzzy!goudreau
USA

Lynn.Lively@p4694.f506.n106.z1.fidonet.org (Lynn Lively) (04/05/90)

In an article of <29 Mar 90 23:52:37 GMT>, goudreau@larrybud.rtp.dg.com (Bob Goudreau) writes:

 BG>Of course, whether naming structs and types in this manner is good
 BG>programming practice is another question entirely.  The coding
 BG>standards for the project that I work on require that we always
 BG>create a typedef for any structs we invent.  Whenever possible (which
 BG>is most of the time), the struct itself has no self-references and
 BG>can thus be unnamed:
 BG>
 BG>        typedef struct
 BG>
 BG>        {
 BG>        a_type  a;
 BG>        b_type  b;
 BG>
 BG>        }       foo_bar_type;
 BG>
 BG>
 BG>Only when there is need for self-reference does the structure get a
 BG>name, and to avoid confusion that name is produced by replacing the
 BG>"_type" in the typedef name with "_tag":
 BG>
 BG>        typedef struct foo_whiz_tag
 BG>
 BG>        {
 BG>        a_type                  a;
 BG>        b_type                  b;
 BG>        struct foo_whiz_tag *   next;
 BG>
 BG>        }       foo_whiz_type;
 BG>

 Bob,
     Another good way of doing it (The one I use) is to have the name of the  
typdef in all caps (like FILE is in stdio.h). If I have a self reference i  
often use the suffix _elem to the lowercase of the type name.

typedef struct list_elem
  {
    ... other fields ...
    struct list_elem * next;
  } LIST;

BTW: I'm currently working on a project using DG C compiler and and generally  
very pleased, but there is one thing that I didn't much like. The way the  
VARARGS macros are set up are not consistent with ANSI (At least, not with the  
reference I have on it (Mark Williams ANSI C Reference)), I have written a set  
of my own that are compliant if you're interested. Also I think there might be  
a bug in your implementation of va_start(), you (DG C, not you personally) add  
1 to the pointer which backs up to the item before the rightmost known  
argument, but the vsprintf() (The only 'v' function I used so far) seems to  
expect the address of the rightmost known argument. This caused me a good deal  
of problems before I rewrote the macros. Also, is there another manual I  
should have besides the C reference and C standard runtime library reference?  
Some of the functions are hardly mentioned (of course the ones I'm interested  
in using (specifically the multi-tasking functions)), I've been gleaning what  
information I can from the header files but this is slow going. Any help would  
be appreciated (BTW: Thanks for WORM.C and DINNER.C they may save me, in that  
they are GOOD example programs).
 Your Servant,
      Lynn