[comp.lang.c] Problem initializing a structure

jeff@cjsa.WA.COM (Jeffery Small) (12/15/88)

Given the following sample test program:

-- sample program -------------------------------------------------------

#include <stdio.h>

static char *menu[] = { "aaa", "bbb", "ccc", 0 };

typedef struct {
	char  **mptr;
	char  *item;
} TEST;

TEST X = { menu, 0 };

main()
{
    X.item = menu[0];

    (void) printf("\t\t%s  %s  %s  %s\n", *menu, menu[0], menu[1], menu[2]);
    return(0);
}
-- end of program -------------------------------------------------------

If you compile and run this program you get the following results:

		aaa  aaa  bbb  ccc

as expected, confirming that *menu and menu[?] are pointers to chars.

Now, what I actually want to do is to assign the value to X.item in the 
initialization statement rather than the assignment statement.  So I make
the following change to the program:

...

TEST X = { menu, *menu };

	-- or --

TEST X = { menu, menu[0] };

...

but when I attempt to compile this I get:

>	"z.c", line 10: illegal initialization

and lint says:

>	(10)  illegal initialization

So my question is why doesn't this initialization work and what should I
actually be doing?

I am working on an AT&T 3B1 running OS3.51 (some hybrid of SYSV.2).
Thanks for any help you may be able to offer.
--
Jeffery Small    (206) 485-5596            uw-beaver!uw-nsr!uw-warp
C. Jeffery Small and Associates                                    !cjsa!jeff
19112 152nd Ave NE - Woodinville, WA  98072           uunet!nwnexus

chris@mimsy.UUCP (Chris Torek) (12/17/88)

[Quoted text below is slightly edited]

In article <154@cjsa.WA.COM> jeff@cjsa.WA.COM (Jeffery Small) writes:
>static char *menu[] = { "aaa", "bbb", "ccc", 0 };
>typedef struct {
>	char  **mptr;
>	char  *item;
>} TEST;
>TEST X = { menu, 0 };

>Now, what I actually want to do is to assign [menu[0]] to X.item in the 
>initialization statement ....
>TEST X = { menu, *menu };
>	-- or --
>TEST X = { menu, menu[0] };
>but when I attempt to compile this I get:
>>	"z.c", line 10: illegal initialization

The value for an initialiser must be a constant.  (Actually, it can be
a sort of `extended' constant, including addresses of statically
allocated variables.)  The name of an array is such a constant, as is a
double-quoted string.  The contents of any variable---even if the
contents of that variable is known to be unchanging---is not such a
constant.

One option is to use

	TEST X = { menu, "aaa" };

but this is probably not satisfactory, as it may generate two copies
of the string {'a', 'a', 'a', '\0'}, so that the comparison

	menu[0] == X.item

will be false (0).  (But, depending on your compiler, it may be true,
or 1.)

The other option is guaranteed to work.  Give the `aaa' string a name:

	static char aaa[] = "aaa";
	static char *menu[] = { aaa, "bbb", "ccc", 0 };

	TEST X = { menu, aaa };

Now both menu[0] and X.item are one of these `constants'---the name of
a statically allocated array---and since they are the same constant,
they must have the same value.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

henry@utzoo.uucp (Henry Spencer) (12/18/88)

In article <154@cjsa.WA.COM> jeff@cjsa.WA.COM (Jeffery Small) writes:
>static char *menu[] = { "aaa", "bbb", "ccc", 0 };
>
>Now, what I actually want to do is to assign the value to X.item in the 
>initialization statement rather than the assignment statement.  So I make
>the following change to the program:
>
>TEST X = { menu, *menu };
>
>but when I attempt to compile this I get:
>>	"z.c", line 10: illegal initialization
>...why doesn't this initialization work...

In the general case, the '*' operator cannot be executed at compile time,
so it is illegal in compile-time initializers.  In this specific case, a
smart compiler could actually compile it, but it is thought desirable to
define whether something is legal C without reference to how smart the
compiler is.

The best you could do would be to define a separate variable to hold "aaa"
and point to it from both menu and X.  This is admittedly inconvenient, but
anyone wanting to initialize complex interlinked structures at compile time
in C had better get used to inconvenience.
-- 
"God willing, we will return." |     Henry Spencer at U of Toronto Zoology
-Eugene Cernan, the Moon, 1972 | uunet!attcan!utzoo!henry henry@zoo.toronto.edu