[comp.lang.c] Declaration puzzler

chase@orc.olivetti.com (David Chase) (10/04/88)

I can't figure out how to declare the type of an array with (say) 10
elements, each of which is that array type.  That is, I want the
non-error effect of

	typedef foo *(foo[10]);

Both the SunOS 3.4 C compiler and the GCC 1.28 compiler hate this
declaration.

The word from Harbison and Steele 2 appears to be (5.4, p. 93)

  "If T is any C type except void or 'function returning ...,'
  the array type 'array of T' may be declared."

Clearly, no matter what "foo *" is, it is not void, and it is not
a "function returning ...".

The word from Kernighan and Ritchie 2 appears to be (A8.9, p. 221)

  "typedef does not introduce new types, only synonyms for types
  that could be specified in another way."

and (A8.6.2, p 217)

  "Any type from which an array is constructed must be complete; it
  must not be an array or structure of incomplete type."

I can succeed, however, if I wrap the array up in a structure, as in

  struct mumble {
    struct mumble * children[10];
  };

or

  typedef struct mumble * glop;

  struct mumble {
    glop children[10];
  };

This is all a little puzzling to me.  If I didn't know that C was
wonderful, I might think that arrays were a second-class type.  It's
nice to know that the Good Books still need High Priests to interpret
them.  Pass me the incense and a dead chicken, please.

By the way, (in reference to a discussion on Duff's device), both
compilers mentioned above to fairly reasonable things with the
following apparently legal (based on a quick scan of H&S 2) trick:

  typedef int bogus[1000];
  typedef struct {
    bogus x;
  } * bogus_wrapper;
  bogus a,b;

  ...

  * (bogus_wrapper) a = * (bogus_wrapper) b;

(Sun spit out a very tight loop, Gcc called bcopy.)

Oh well.  Back to work.  I don't know why I ask questions like this,
since I already know the answer.

David
(chase@orc.olivetti.com, or oliveb!orc!chase, but NOT oliveb!chase)

gwyn@smoke.ARPA (Doug Gwyn ) (10/05/88)

In article <30091@oliveb.olivetti.com> chase@orc.olivetti.com (David Chase) writes:
>I can't figure out how to declare the type of an array with (say) 10
>elements, each of which is that array type.

You can't.  A C type cannot contain itself (although it CAN contain
pointers to instances of itself, under some circumstances).

>This is all a little puzzling to me.  If I didn't know that C was
>wonderful, I might think that arrays were a second-class type.

Arrays ARE second-class citizens in C.  This is quite well known.

However, the problem is that you're trying to do two things in
one declaration.  Use two declarations, the first for an
incomplete type and the second using that incomplete type to
help define a complete type of the desired shape.
You will have to resign yourself to using structures for this,
since a type has to be ultimately expressable in terms of basic
types, bit fields, etc. or pointers to structures.

Are you sure you really need a type like that?

davidsen@steinmetz.ge.com (William E. Davidsen Jr) (10/05/88)

In article <30091@oliveb.olivetti.com> chase@orc.olivetti.com (David Chase) writes:
| I can't figure out how to declare the type of an array with (say) 10
| elements, each of which is that array type.  That is, I want the
| non-error effect of
| 
| 	typedef foo *(foo[10]);

why not:
	typedef int foo[10];
	typedef foo *bar;

Perhaps that will do what you want to do, if not the way you want. The
token after the 'typedef' must be a type, and it seems that foo doesn't
become a type until after compilation of the typedef.
-- 
	bill davidsen		(wedu@ge-crd.arpa)
  {uunet | philabs}!steinmetz!crdos1!davidsen
"Stupidity, like virtue, is its own reward" -me

chase@Ozona.orc.olivetti.com (David Chase) (10/06/88)

In article <8633@smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <30091@oliveb.olivetti.com> chase@orc.olivetti.com (David Chase) writes:
>>I can't figure out how to declare the type of an array with (say) 10
>>elements, each of which is that array type.

If that's what I said, then I made a typo.  I meant "each of which is a
pointer to that array type".

>Are you sure you really need a type like that?

I don't necessarily, but it would be handy to have it.  Ask me about
using C for an intermediate language if you'd like an earful.

David

diamond@csl.sony.JUNET (Norman Diamond) (10/06/88)

In article <30091@oliveb.olivetti.com>, chase@orc.olivetti.com (David Chase) writes:
> I can't figure out how to declare the type of an array with (say) 10
> elements, each of which is that array type.  That is, I want the
> non-error effect of
> 
> 	typedef foo *(foo[10]);
> 
                ^#1   ^#2

The problem is that you're trying to use foo #1 to define foo #2.
At the time of using foo (#1), it hasn't been defined yet.  Except
for structure tags (and other similar tags), you cannot use an
identifier before it is declared.
 
>   "If T is any C type except void or 'function returning ...,'
>   the array type 'array of T' may be declared."

An undefined identifier is not any C type.
 
> I can succeed, however, if I wrap the array up in a structure, as in
> 
>   struct mumble {
>     struct mumble * children[10];
>   };

Yes ... structs are maybe 0th-class citizens, ahead of 1st-class.
 
> I might think that arrays were a second-class type.

You also can't do typedef bar bar; or typedef flub flub(); or
typedef plunk *plunk; so arrays don't seem to be second to most
other types.
-- 
-------------------------------------------------------------------------------
  The above opinions are my own.   |   Norman Diamond
  If they're also your opinions,   |   Sony Computer Science Laboratory, Inc.
  you're infringing my copyright.  |   diamond%csl.sony.jp@relay.cs.net

dharvey@wsccs.UUCP (David Harvey) (10/09/88)

In article <30091@oliveb.olivetti.com>, chase@orc.olivetti.com (David Chase) writes:
> I can't figure out how to declare the type of an array with (say) 10
> elements, each of which is that array type.  That is, I want the
> non-error effect of
> 
> 	typedef foo *(foo[10]);
> 
> I can succeed, however, if I wrap the array up in a structure, as in
>
	[omitted rest] 
> 
> Oh well.  Back to work.  I don't know why I ask questions like this,
> since I already know the answer.

If you really know the answer, then illuminate the masses.  Enquiring
minds want to know.  Seriously, what do you intend to use this type of
structure for?  An array of arrays that point to themselves?  Hmm,
methinks I smell some mischief.

dharvey@wsccs

tongue-in-cheek

I am responsible for Nobody,
and Nobody is responsible for me.
The only thing you can know for sure,
is that you can't know anything for sure.

chase@Ozona.orc.olivetti.com (David Chase) (10/13/88)

In article <717@wsccs.UUCP> dharvey@wsccs.UUCP (David Harvey) writes:
>In article <30091@oliveb.olivetti.com>, chase@orc.olivetti.com (David Chase) writes:
>> 	typedef foo *(foo[10]);
>minds want to know.  Seriously, what do you intend to use this type of
>structure for?  An array of arrays that point to themselves?  Hmm,
>methinks I smell some mischief.

Well, you could call it mischief.  In the interests of having a
compiler for Modula-3 that is easy to port, we're generating C.  The
justification is that since it is possible to declare such an type in
Modula-3, and we are compiling Modula-3, then we must generate some
declaration for it (much as I am tempted, it is not considered good
form for a compiler to offer snide comments on legal programs).  I was
cheerfully spitting out declarations for all sorts of things, but had
a problem involving arrays.  The problem eventually reduced itself to
the example which I presented.  I got pretty PO'd, and posted (I know,
Ms. Net-manners says not do to that; allow me an occasional slip).

As a workaround, we are wrapping all arrays up inside structures.
This also gets us proper semantics for array assignment and parameter
passing, so it isn't too much of a disaster.  However, doing this
makes me distinctly uneasy about the correctness/portability of
addressing arithmetic performed for (multi-dimensional) open arrays.
Ugh.

By the way, anyone out there that thinks that C is a great
intermediate language should think again.  I was going to flame at
length, but decided not to.

David