Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!seismo!mcvax!unido!iaoobelix!wagner
From: wagner@iaoobelix.UUCP
Newsgroups: comp.lang.c
Subject: Re: A Deficiency of the C Preprocessor - (nf)
Message-ID: <6700002@iaoobelix.UUCP>
Date: Mon, 22-Dec-86 00:17:00 EST
Article-I.D.: iaoobeli.6700002
Posted: Mon Dec 22 00:17:00 1986
Date-Received: Tue, 23-Dec-86 23:40:26 EST
References: <1259@kontron.UUCP>
Lines: 79
Nf-ID: #R:kontron:-125900:iaoobelix:6700002:000:2538
Nf-From: iaoobelix!wagner    Dec 22 06:17:00 1986

> > I've got a complaint about the C preprocessor -- I doesn't support a
> > repetition for initializing data structures.
> >
> > We are developing programs where an array of structures exists.
> >
> >         #define BRKPTCOUNT      5
> >         struct .... FooBar[BRKPTCOUNT] = {....};
> >
> > Everytime we change BRKPTCOUNT, we have to change the initialization data
> > for FooBar; if we give extra initialization data, we get complaints from the
> > compiler; if we don't give enough data, the rest of the structure isn't
> > initialized.
> 
> Why don't you write your structures and defines like this:
> 
>     #define BRKPTCOUNT  (sizeof (FooBar)/sizeof (FooBar[0]))
>     struct ... FooBar [] = { ... } ;
> 
> Then your array will be maid as large as needed to fit your data.
> The size of the array (defined by BRKPTCOUNT) will be computed during
> compile time, since sizeof is a compile time function and the whole
> expression is constant.
> 

I think, it is still a problem if you want the data structure  to
be  initialized  with  exactly  `n' identical elements (well, not
idential: with 'n' elements containing the  same  values).  Then,
cpp  is  really lacking a means of introducing repetitions of the
kind mentioned above. Determining the actual number  of  elements
in  that  array is no problem, as Dieter has already pointed out.
Yet, my solution to your problem would be the following (it is  a
quick hack, I know...):

>>file foo.c

	# define BRKPTCOUNT 5
	# define FooBar_INIT { ... }
	struct s_frob FooBar[] = {
	# include "FooBar-init.h"
		};
	...

Your Makefile will then contain some instructions for generating
FooBar-init.h, finally containing `n' times the appropriate symbol
FooBar_INIT, separated by commas.

Anyway, if you don't like this solution (I don't like it, too), try
use the m4 macro preprocessor instead of cpp. M4 allows calling UNIX
programs from within the preprocessor. Example:

>>file rep.c
	# include 

	main(argc,argv)
	int argc;
	char **argv;
	{
	   int i;
	
	   if (argc == 3)
	      for (i=atoi(argv[1]); i>0; i--)
		 printf("%s%s\n", argv[2], i==1 ? "" : ",");
	}

>>file foo.c (containing the macro calls)
	...
	define(BRKPTCOUNT, 5)
	define(ITEM, foo)
	syscmd(rep BRKPTCOUNT ITEM)
	...

This will insert BRKPTCOUNT times the string specified by ITEM into
your source file... (basically the same procedure as above).

I hope this is of use,

Juergen Wagner,			(USENET)   ...!unido!iaoobel!wagner
					        wagner@iaoobel.UUCP
	 			Fraunhofer Institute IAO, Stuttgart