[net.lang.c] typedef follies

glenn (04/14/83)

We recently bruised our shins on a murky area of C: typedefs.  The
following definitions and declarations illustrate the problem.
	typedef struct a {
		int	b, c;	/* details irrelevant here */
	} a;
Now consider these declarations:
	struct a	a;	/* try #1 */
	a		a;	/* try #2 */

The 4.1 version of pcc accepts neither of these, complaining about
syntax errors and old-fashioned intializers for try #1 and about an
illegal type combination for try #2.  We don't have access to the
Ritchie compiler; how does it behave on these declarations?

It is tempting to think that, at least for try #1,the problem is that
the structure tag is the same as the variable name.  Things aren't that
simple, since the following works:
	struct a {		/* try #3 */
		int	b, c;
	};
	struct a	a;

Of course, the real question is whether either of the first two
declarations is (or should be) legal C.  Not surprisingly, the white
book is vague about the fine points of typedefs and doesn't settle the
issue.

My own opinion is that both should be legal.  Try #2 is unambiguous; the
occurrence of `a' following `struct' can only be a structure tag.  Try
#1 is potentially ambiguous; we can view it either as the declaration of
an (implicit) int initialized to itself or as the declaration of a
variable named `a' of type `a'.  Viewed the first way, the construct is
illegal, since the initializer is not a constant expression or an
address.  Viewed the second way, the construct seems acceptable.  If we
agree that it is time for old-fashioned initializers (without an equal
sign) to go the way of the dodo, try #2's ambiguity disappears leaving
only the second, preferred, interpretation.

		-- Glenn Skinner
		...!ucbvax!menlo70!nsc!glenn