[net.lang.c] Followup to Very Tough C Riddle

sam@delftcc.UUCP (Sam Kendall) (04/22/86)

Here is the followup to my "Very Tough C Riddle".  The riddle was posted
about a hundred years ago.  Thanks to harvard!draves, Ron Natalie
<ron@BRL-TGR.ARPA>, Tony Li <Tli@Usc-Eclb>, vu44!jack, enmasse!mike,
hadron!jsdy@seismo.ARPA (Joseph S. D. Yao), qtlon!ist!istbt!rb, and
callan!tim (Tim Smith) for replying, and my apologies for the long delay
in posting this followup.

Here is the original note:

>	Is the token sequence
>
>		[ ] [ ]
>
>	legal anywhere in a C program as defined in K&R?  If so, where
>	and why?  If not, why not?
>
>	Warning: some may consider the solution debatable, although I
>	will endeavor to prove them wrong, i.e., I am pretty sure I
>	have the correct answer.

    Now, on to the solutions.  The answer is YES, contrary to plenty of
replies!  (Except that the word "anywhere" in the note should be
"somewhere", as Tim Smith pointed out.)  To see this, we don't have to
depend on my debatable solution; qtlon!ist!istbt!rb provided a clear
solution that no one else (including myself) thought of:

>	How about:
>
>		/* [ ] [ ] */
>		"  [ ] [ ] "
>
>	or (more seriously):
>
>		#define FRED [ ] [ ]
>
>	where FRED does not appear elsewhere.

In the FRED line, `[ ] [ ]' is indisputably a token sequence, for K&R
section 12.1 gives the syntax of such lines as `#define identifier
token-string'.  (The reason, of course, that rb isn't serious about the
first two is that in a comment or a string, the brackets are not a
"token sequence", only part of a single token.)

     Even though it's not necessary for the riddle's solution, let's
take a look at the other possibility, which is for there to be a formal
parameter declaration of the form

        type formal[][];

Tony Li and Joe Yao mentioned this possibility, but they didn't think
it was legal.  The passage mentioned in K&R that many people think
prohibits any adjacent pairs of empty brackets is this:

        When several adjacent "array of" specifications are adjacent, a
        multi-dimensional array is created; the constant expressions
        which specify the bounds of the arrays may be missing only for
        the first member of the sequence.  (section 8.4)
        
The passage that may allow `[ ] [ ]' for formal parameters is this
(first elipsis mine):

        ...  [D]eclarations of formal parameters declared "array of ..."
        are adjusted to read "pointer to ...".  (section 10.1)
        
This passage is why, in my interpretation,

        type formal[][];

"is adjusted to read"

        type (*formal)[];

This second type is "pointer to array of unknown length".  However
strange the idea of a pointer to an object of unknown length, note that
this type is legal according to section 8.4, as quoted above.  There is
a sequence of one "array of" specification, and the bounds are missing
only for the first (and only) member of the sequence.  (Aside: this type
is also usable, since you don't need to know the length of an array to
access it.  I have seen it, for you trivia fans, used erroneously in the
System V Release 0 semop(2) man page and lint library entry.  A question
for debate: should it be legal in ANSI C?  I can see both sides of the
question.)

     The question, then, is whether 8.4 supercedes 10.1, whether the
type of a formal argument has to be legal before as well as after it is
rewritten.  I was going to argue that it does not have to be, and if I
were in a debate, I would keep going.  But I have convinced myself that
the question is, at best, up in the air.  No sane programmer would
intentionally write a formal argument declaration with `[ ] [ ]', even
with one pair of braces hidden by typedefs.  Even as an academic
exercise -- which is all this article is, of course -- I can't stomach
arguing for this dark corner of C.  There is an interesting question
about whether to consider dark corners to be in a language or not, but
that question is beyond the scope of this article.

----
Sam Kendall			{ ihnp4 | seismo!cmcl2 }!delftcc!sam
Delft Consulting Corp.		ARPA: delftcc!sam@NYU.ARPA

jsdy@hadron.UUCP (Joseph S. D. Yao) (05/08/86)

AARRGGHHHHHHHHHHH!!!!!

In article <140@delftcc.UUCP> sam@delftcc.UUCP (Sam Kendall) writes:
>     Even though it's not necessary for the riddle's solution, let's
>take a look at the other possibility, which is for there to be a formal
>parameter declaration of the form
>        type formal[][];
>Tony Li and Joe Yao mentioned this possibility, but they didn't think
>it was legal.  The passage mentioned in K&R that many people think
>prohibits any adjacent pairs of empty brackets is this:
>        multi-dimensional array ...		may be missing only for
>        the first member of the sequence.  (section 8.4)
>The passage that may allow `[ ] [ ]' for formal parameters is this
>(first elipsis mine):  [other ellipses mine -jsdy-]
>        ...  [D]eclarations of formal parameters declared "array of ..."
>        are adjusted to read "pointer to ...".  (section 10.1)
>    ... type formal[][]; "is adjusted to read" type (*formal)[];
>This second type is "pointer to array of unknown length".

Sam, this is not legal, has never been legal, and (pray God) will
never be legal.  One may have the first member of the [] sequence
empty because, from the rest, one can determine the size of each
member of the array.  One may not have pointers to or arrays of
items of which one does not know the size.  To see why this is so,
tell me: what do arrname[1] or *++ptr reference????

By the way -- section 10.1 cited above refers, of course only to the
outermost (first) []'s.  Do you remember the long essay on this a
year or two ago?  [I don't ... if you have a copy, please send it
to me ... ]
-- 

	Joe Yao		hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP}