[comp.lang.c] mutual reference in structures

bouma@cs.purdue.EDU (William J. Bouma) (05/05/89)

Please tell me how to get C to accept the following or equivalent code:

typedef union a {
    b_ *pb;
} a_;

typedef struct b {
    a_ va;
} b_;


-- 
Bill <bouma@cs.purdue.edu>  ||  ...!purdue!bouma 

heather@maui.cs.ucla.edu (Heather Burris) (05/05/89)

In article <6712@medusa.cs.purdue.edu> bouma@cs.purdue.EDU (William J. Bouma) writes:
>Please tell me how to get C to accept the following or equivalent code:
>
>typedef union a {
>    b_ *pb;
>} a_;
>
>typedef struct b {
>    a_ va;
>} b_;
>
>
>-- 
>Bill <bouma@cs.purdue.edu>  ||  ...!purdue!bouma 

You cannot do forward references on typedefs.  You can, however,
on structure tags.  Therefore you can say:

typedef union a{
	struct b *pb;
}a_;

typedef struct b{
	a_ va;
}b_;

Note that the order of the above declarations is important because
I have not removed the typedef reference to typedef a_.  Have fun,

Heather Burris, UCLA

schaefer@ogccse.ogc.edu (Barton E. Schaefer) (05/05/89)

In article <23608@shemp.CS.UCLA.EDU> heather@cs.ucla.edu (Heather Burris) writes:
} In article <6712@medusa.cs.purdue.edu> bouma@cs.purdue.EDU (William J. Bouma) writes:
} >Please tell me how to get C to accept the following or equivalent code:
} >
} >typedef union a {
} >    b_ *pb;
} >} a_;
} >
} >typedef struct b {
} >    a_ va;
} >} b_;
} 
} You cannot do forward references on typedefs.  You can, however,
} on structure tags.

Both DYNIX cc and gcc -ansi -pedantic accept the following without complaint:

/* --------------- */
typedef struct b b_;

typedef struct a {
	b_ *bp;
} a_;

struct b {
	a_ *ap;
};
/* --------------- */

Is there something I'm missing here?
-- 
Bart Schaefer       "And if you believe that, you'll believe anything."
							-- DangerMouse
CSNET / Internet                schaefer@cse.ogc.edu
UUCP                            ...{sun,tektronix,verdix}!ogccse!schaefer

geoff@cs.warwick.ac.uk (Geoff Rimmer) (05/05/89)

In article <6712@medusa.cs.purdue.edu> bouma@cs.purdue.EDU (William J. Bouma) writes:

> Please tell me how to get C to accept the following or equivalent code:
> 
> typedef union a {
>  b_ *pb;
> } a_;
> 
> typedef struct b {
>  a_ va;
> } b_;
> 
> Bill <bouma@cs.purdue.edu>  ||  ...!purdue!bouma 

typedef union a {
    struct b *pb;
} a_;

typedef struct b {
    a_ va;
} b_;

Geoff

	/---------------------------------------------------------------\
	|	GEOFF RIMMER  - Friend of fax booths, ANSI C, PCBH,	|
	|			American Cable TV & MPFC & VCRs		|
	|	email	: geoff@uk.ac.warwick.emerald			|
	|	address : Computer Science Dept, Warwick University, 	|
	|		  Coventry, England.				|
	|	PHONE	: +44 203 692320 (10 lines)			|
	|	FAX	: +44 865 726753				|
	\---------------------------------------------------------------/

dg@lakart.UUCP (David Goodenough) (05/08/89)

From article <6712@medusa.cs.purdue.edu>, by bouma@cs.purdue.EDU (William J. Bouma):
> Please tell me how to get C to accept the following or equivalent code:
> 
> typedef union a {
>     b_ *pb;
> } a_;
> 
> typedef struct b {
>     a_ va;
> } b_;

Trivial.

Get rid of the typedefs.

union a {
    struct b *pb;
};

struct b {
    union a va;
};

works just fine on my compiler. (Greenhills family)

Yet another reason not to get typedef happy :-)
-- 
	dg@lakart.UUCP - David Goodenough		+---+
						IHS	| +-+-+
	....... !harvard!xait!lakart!dg			+-+-+ |
AKA:	dg%lakart.uucp@xait.xerox.com		  	  +---+

jym@wheaties.ai.mit.edu (Jym Dyer) (05/11/89)

VAX C accepts this (which seems wrong to me):

	typedef struct
	{
	  struct NODE_T *  flink_p;
	  struct NODE_T *  blink_p;
	  char  data[512];
	}  NODE_T;

It would be nice if C typedefs knew about themselves.  That is, if this
    worked:

	typedef
	{
	  NODE_T *  flink_p;
	  NODE_T *  blink_p;
	  char  data[512];
	}  NODE_T;

    <_Jym_>

chris@mimsy.UUCP (Chris Torek) (05/11/89)

In article <2346@wheat-chex.ai.mit.edu> jym@wheaties.ai.mit.edu
(Jym Dyer) writes:
>VAX C accepts this (which seems wrong to me):
>
>	typedef struct
>	{
>	  struct NODE_T *  flink_p;
>	  struct NODE_T *  blink_p;
>	  char  data[512];
>	}  NODE_T;

This is legal; it is merely stupid.  It is the moral equivalent of

	typedef struct {
		struct never_defined *forw;
		struct never_defined *back;
		char data[512];
	} NODE_T;

Here, you cannot use the pointers `forw' and `back' without first
declaring a structure tag `struct never_defined'.  In the quoted
article, you cannot use the pointers `flink_p' and `blink_p' because
there is no `struct NODE_T' (there is only a NODE_T; the typedef
is in a different namespace from structure tags).

>It would be nice if C typedefs knew about themselves ... :
>
>	typedef
>	{
>	  NODE_T *  flink_p;
>	  NODE_T *  blink_p;
>	  char  data[512];
>	}  NODE_T;

This would require the ability to `back up', or at least to defer
`thinking about' the declaration.  There is nothing in C that now
requires this, so it would be in effect a radical change.

What is so wrong with


	typedef struct node_t {
		struct node_t *flink_p;
		struct node_t *blink_p;
		char data[512];
	} NODE_T;

anyway?
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

gwyn@smoke.BRL.MIL (Doug Gwyn) (05/12/89)

In article <2346@wheat-chex.ai.mit.edu> jym@wheaties.ai.mit.edu (Jym Dyer) writes:
-VAX C accepts this (which seems wrong to me):
-	typedef struct
-	{
-	  struct NODE_T *  flink_p;
-	  struct NODE_T *  blink_p;
-	  char  data[512];
-	}  NODE_T;

That's valid, but "struct NODE_T" is still an incomplete type afterwards.
The final NODE_T is the type name being defined, not a structure tag.

mat@mole-end.UUCP (Mark A Terribile) (05/13/89)

In article <2346@wheat-chex.ai.mit.edu>, jym@wheaties.ai.mit.edu (Jym Dyer) writes:

> VAX C accepts this (which seems wrong to me):
 
> 	typedef struct
> 	{
> 	  struct NODE_T *  flink_p;
> 	  struct NODE_T *  blink_p;
> 	  char  data[512];
> 	}  NODE_T;


Why does it seem wrong?  Yes, C accepts a structure tag before the structure's
form is available.  Without this leniency, you need either to allow forward
declarations (a pain and easy to get wrong) or to forgo any use of linked
lists.

 
> It would be nice if C typedefs knew about themselves.  That is, if this
>     worked:


Now you are getting into there area where forward declarations would be
needed.

 
> 	typedef
> 	{
> 	  NODE_T *  flink_p;
> 	  NODE_T *  blink_p;
> 	  char  data[512];
> 	}  NODE_T;


The parser has to know that NODE_T is a type.  (This isn't absolutely true,
but if the grammar doesn't assume that lexical analysis can tell a type from
an ordinary identifier, you have push a much worse problem into semantic
analysis.)  It doesn't know that NODE_T is a type until the declaration has
been processed.

This is where you start talking about forward declarations.
-- 

 (This man's opinions are his own.)
 From mole-end				Mark Terribile