rules for transforming casts to declarations?

der Mouse mouse at mcgill-vision.UUCP
Wed Mar 29 20:54:42 AEST 1989


In article <3698 at tekcrl.LABS.TEK.COM>, stevev at tekchips.LABS.TEK.COM (Steve Vegdahl) writes:
> [is building something to transform casts to declarations]

> Not being an expert on C type-declarations, I would appreciate
> opinions as to whether this method handles all cases and, if not,
> some examples cast-expressions on which it will fail.

> Alleged algorithm for transforming cast into a declaration.
[compressed slightly -dM]
>   1. strip away the outer parentheses of the cast expression
>   2. find the position to insert the to-be-declared identifier:
>       a. skip over all identifiers, left parentheses, and asterisks
[You have to treat type keywords as "identifiers" to make that work]
>       b. if we stopped just after ( and just before ), back up
>   3. insert the identifer in the current position
>   4. add a semicolon to the end

I think this is correct, though I am not at all certain.

In a declaration, the only things that can appear before the identifier
being declared are certain keywords, typedef names, left parentheses,
and *s.  (This is based on an examination of the grammar in the back of
K&RV2; I'm sure I'll be, er, "corrected" if I'm wrong.)

However, the identifier does not necessarily fit into the spot found by
the above algorithm, though I *think* it will, provided the cast is
legal.  (Definitely not for some illegal casts; consider, for example,
(int ()), a cast to function returning int (which isn't legal).  Your
algorithm will place the identifier so as to make this a declaration of
an int variable.)  All the cases I have been able to construct where
the algorithm fails involve casts to function types; I have tried to
convince myself this must be so, but so far have failed.

> (Is the algorithm for going the other direction simply that of
> removing the declared name and the semicolon and surrounding the
> entire thing with parentheses?)

You have to remove at least some redundant parentheses first.  For
example,

int (foo);

declares foo as an int, but

(int ())

is the (pseudo-)cast I mentioned above to function-returning-int.

I find this disturbing, in view of the statement near the top of page
221 of K&RV2, when discussing abstract types (as used in, eg, casts):

	It is possible to identify uniquely the location in the
	abstract-declarator where the identifier would appear if the
	construction were a declarator in a declaration.

As far as I can see, the only thing that allows us to deduce that
(int ()) is a cast to function-returning-int rather than to int is the
fact that "int foo();" is semantically illegal, while "int (foo);" is
legal.  Huh?  Isn't that backwards?  And wait a minute!  "int foo();"
*is* legal - when foo is a formal parameter: see the paragraph
beginning on the fifth line of page 226.  Yet I'm sure that (int ()) is
understood as a cast to function rather than to int; our (pcc-based)
compiler certainly does this ("illegal lhs of assignment operator", not
the best possible error), and while pcc does some strange things, a
basic misunderstanding of casts strikes me as unlikely to be among
them.

Is this apparent weirdness due to (a) a real ambiguity, (b) me being
confused about something, or (c) K&R being less pedantic than the
(p)ANS in their wording?  (Or something else?)

					der Mouse

			old: mcgill-vision!mouse
			new: mouse at larry.mcrcim.mcgill.edu



More information about the Comp.lang.c mailing list