[net.lang.c] Why can't I do this?

ptw@vaxine.UUCP (P. T. Withington) (01/12/84)

I (foolishly) presumed by analogy with:

static char *foo[] = {"hello",
                      "out",
                      "there"};

that I could:

static int *bar[] = {{0, 1, 2},
                     {3, 4},
                     {5, 6, 7, 8}};

but I can't.  My compiler (4.2) pukes with:

xxxxxx.c(NN): compiler error: initialization alignment error

Why?  Should it?

                                --ptw

mjs@rabbit.UUCP (M. J. Shannon, Jr.) (01/13/84)

WHat you probably want to say is:
	static int int_array[][] =
	{
		{ 0, 1, 2, 3, /* padded to longest */ },
		{ 17, 42 },
		{ 11, 15, 57 },
	};

What is meant by what you said is: initialize an array of pointers.
You can't initialize a pointer with an aggregate.  The reason it works
for strings is that the type of "foo" is `char *'.  There is no way of
using the same sort of syntax to do the same for int arrays.
-- 
	Marty Shannon
UUCP:	{alice,rabbit,research}!mjs
Phone:	201-582-3199

keesan@bbncca.ARPA (Morris Keesan) (01/14/84)

-----------------------------
P.T.Withington asks if 

>>  static char *foo[] = {"hello",
>>                        "out",
>>                        "there"};

is legal, why isn't

>>  static int *bar[] = {{0, 1, 2},
>>                       {3, 4},
>>                     {5, 6, 7, 8}};

legal?  First, let's look at the declarations aside from the initialization.
Both identifiers are declared to be arrays of pointers, and as such should be
initialized with pointers.  Note also that initializers must be constants.
"hello" is a genuine constant, representing a pointer to the array
{'h','e','l','l','o','\0'} somewhere in memory.  However, strings are the only
case where an aggregate can be represented as a constant, and that's because
the value is really the address.  {0, 1, 2} is not a constant expression, nor
is it an aggregate or the address of an aggregate -- and the only place the
it can legally appear in a C program is as an initializer.  Note that the
same thing is true of {'h','e','l','l','o','\0'} -- it can only be an
initializer.

    I hope you realize that foo, above, does not contain any of the characters
represented -- sizeof foo == 3 * sizeof(char *).  If you really want bar to be
an array of pointers also, a way to declare it would be
    static int bar1[] = {0,1,2}, bar2[] = {3,4}, bar3[] = {5,6,7,8};
    static int *bar[] = { bar1, bar2, bar3 };
where bar1, bar2, and bar3 in the initializer for bar are the addresses of the
respective arrays.
-- 
					Morris M. Keesan
					{decvax,linus,wjh12}!bbncca!keesan
					keesan @ BBN-UNIX.ARPA

ptw@vaxine.UUCP (P. T. Withington) (01/16/84)

Well.  I got lots of replies to my query that told me I couldn't do what I
wanted to do because I was doing something illegal.  Well, I knew that.  The
compiler told me so.  I guess what I really should have asked is:  "How can I
do this"?  It seemed to me that there ought to be a way to initialize an array
of pointers to things other than char.  Two solutions were suggested:

1) Don't do it that way; declare it as a ?*n array (either implicity or
explicitly).  Which wastes the space I was trying to conserve.  (? is really
very large in my case and n ranges between 3 and 7.)

2) Declare a lot of useless 1-dim arrays followed by a declaration of the array
of pointers.  Which is more in the spirit of things, but since ? is so big
(see above) leads to a lot of unnecessary clutter and doesn't sound like C to
me.

I thought that maybe:

int *bar[] = {&{0, 1, 2, ...

would do, but my compiler doesn't like that either.  Of course, my ints are all
very small so I *could* say:

char *bar[] = {"\0\1\2", ...

Yuk!

Maybe it's just not important to worry about that many bytes any more.  Maybe
its something that just isn't done enough to create a hulluballoo over.

                                          -ptw