Help, page 197 K&R !!!

Chris Torek chris at mimsy.UUCP
Sun Jul 2 06:00:04 AEST 1989


>>In article <646 at kl-cs.UUCP> atula at cs.keele.ac.uk (Atula Herath) asks:
>>>Could somebody please explain me [paragraph 7, p.197 of K&R-1]

>In article <648 at kl-cs.UUCP> pc at cs.keele.ac.uk (Phil Cornes) writes:
>>K&R C says that member names in structures and unions must (in general) be
>>unique. This is because in early implementations the names of structure and
>>union members were not associated with their parent names but were only stored
>>as a type and offset from the start of the parent.

This is correct.  These early implementations had all but vanished by
the time K&R 1st ed. started selling, and the note in the appendix was
rather more harm than help.

In article <CLINE.89Jul1102015 at sun.soe.clarkson.edu>
cline at sun.soe.clarkson.edu (Marshall Cline) writes:
>Another reason: K&R C (and ANSI[??] -- I don't know) allow[ed|s] a pointer
>to be implicitly cast to a pointer-to-struct if the appropriate "->field"
>was given.

This is no longer true.  PCC accepted the `old' construct but with a
warning (or a fatal error if the member name was not unique).  Some
PCCs no longer accept these ever.

As I explained not long ago in this very same newsgroup, once upon a
time C had no unions.  Instead of

	struct symbol {
		char	*sym_name;
		int	sym_type;	/* one of SYM_INT or SYM_FLOAT */
		union {
			int su_int;
			float su_float;
		} sym_un;
	};

		...
		struct symbol *p = ...;
		if (p->sym_type == SYM_INT)
			ival = p->sym_un.su_int;
		else
			fval = p->sym_un.su_float;
		...

one wrote

	struct symbol {
		char	*sym_name;
		int	sym_type;	/* SYM_INT */
		int	sym_int;
	};
	struct fsymbol {
		char	*sym_name;
		int	sym_type;	/* SYM_FLOAT */
		float	sym_float;
	};

		...
		struct symbol *p = ...;
		if (p->sym_type == SYM_INT)
			ival = p->sym_int;
		else
			fval = p->sym_float;
		...

>Something like the following:
>
>	typedef struct {int squiggle, wiggle;} worm_t;
>	main()
>	{	char	*p;
>		...
>		p->squiggle = 3;  /* implicit cast of "p" to "(worm_t *)p" */
>		...
>	}

This was allowed in the same pre-union days, but only as a side effect
of never looking at both the left and right sides of the `->' operator
at the same time.  The compiler treated `->' as

	fetch offset via rhs value
	add offset to lhs value
	load word (size determined by rhs type) from pointer result

and, since all pointers were the same size as an int---after all, the
language only ran on PDP-11s, not IBM PCs with mixed models or the
like---the only requirement was that the lhs not be floating point.
(`long' did not exist then.)  One could and did legitimately write
such things as

	0777440->csr |= RK_GO;	/* start the disk */

It did not take long for this approach to be discarded.  (But, surprise
surprise, it still works in the 4BSD compiler.  Of course, you have to
use 0x20100000+0777440 on a VAX-11/780.)

>I personally have never used this, as it seems left over from the days when
>typedef's were discouraged (what some call "Classic C").

It is left over from days much further agone.  Like Classic Coke,
Classic C had a number of formulations.  This little bit of
type-ignorance is akin to the cocaine in Coca-Cola, not the sugar.
(Coke dropped the cocaine content in the early 1900s, and switched from
`cane sugar' to `cane sugar or corn syrup, whichever is cheaper' in the
late 1900s.  But they only changed the *amount* of sugar recently, when
New Coke appeared.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at mimsy.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.lang.c mailing list