vector initialization

Steve Summit scs at adam.pika.mit.edu
Thu Jun 8 13:00:29 AEST 1989


In article <687 at lakesys.UUCP> chad at lakesys.UUCP (Chad Gibbons) writes:
>Question: is it possible to initialize a vector?
>...in the context of something
>along these lines (from a command list vector):
>
>typedef struct _com {
>    char **words;
>    int (*fcn)();
>    short flags;
>} COM;
>
>...and then initializing the structure in another module by:
>
>COM foo[] = {
>    { "one", "two", "three", NULL }, do_num, 0,
>    { "exit", "quit", NULL }, quit, 0
>};
>
>That would be nice, but something tells me it isn't C, or anything else
>like it.  I may resort to allowing only a single word per structure, but
>it would be more advantageous to use a list associated with a single
>structure entry.

In article <17940 at mimsy.UUCP> chris at mimsy.UUCP (Chris Torek) writes:

>You need an object of type `pointer to pointer to char'.  An array of
>pointer to char would suffice, if you could create one without giving
>it a name, because it would decay into a pointer to pointer to char.
>But you cannot create one without naming it...
>For each of the two COM objects foo[0] and foo[1], you need a constant
>value of type `char **'.  So what we *can* do is this:
>
>	char *xxx0[] = { "one", "two", "three", NULL };
>	char *xxx1[] = { "exit", "quit", NULL };
>
>	COM foo[] = {
>		{ xxx0, do_num, 0 },
>		{ xxx1, quit, 0 },
>	};

The other way is to modify the declaration, so that you don't
need a pointer:

	typedef struct {
		char *words[MAXWORDS];
		int (*fcn)();
		short flags;
	} COM;

	COM foo[] = {
		{{ "one", "two", "three", NULL }, do_num, 0,},
		{{ "exit", "quit", NULL }, quit, 0,},
	};

This has the advantage that you don't need to think of names for
the placeholder pointers.  It has the disadvantages that the
number of entries is limited, and space is wasted if there are
many lists with considerably fewer than MAXWORDS entries.

Note that the initialization of this latter form is exactly as
Chad speculated (although I have added extra braces and commas,
as Chris did).  In fact, you can leave out the explicit NULLs as
list endmarkers, because uninitialized char *'s (in this case,
the entries out to MAXWORDS) are guaranteed to be set to null
pointers.  (For God's sake, if you don't understand this, don't
post a followup!)  The code scanning the list would be
well-advised to terminate after either seeing a NULL or
exhausting MAXWORDS words, whichever comes first.  Accessing the
words list is otherwise (syntactically) identical to the full
pointer version.

The method using dummy arrays, which Chris illustrated, is
generally preferable, especially if you don't mind making up
names.  I often write preprocessors for application-specific
aggregate initializations of this sort, which generate the
intermediate arrays and dummy names automatically.

                                            Steve Summit
                                            scs at adam.pika.mit.edu



More information about the Comp.lang.c mailing list