[comp.lang.c] initializing to expressions

BRL102@psuvm.psu.edu (Ben Liblit) (02/09/91)

I want to initialize an array with values that are constant, but are in the
form of expressions.  For example,

   double  value[ 2 ] = { sqrt( 2 ) / 2, cos ( sqrt( 5 ) ) };

Is there any way to accomplish this?  I know I could do this in some sort of
'for' loop, or else by assigning values explicitly.  I'd really like to avoid
this, though, as having the initialization in the declaration area would be much
more readable.  The example above is a simplification -- the actual arrays are
quite large and explicit, individual assignment would be too cluttering.

Is there *any* way to convince my compiler (High C Compiler version 2, off of a
Unix box) to give me this sort of initialization within the declaration area?

                            Ben Liblit
                            BRL102 @ psuvm.psu.edu -- BRL102 @ psuvm.bitnet
                            Liblit @ endor.cs.psu.edu
                            "Fais que tes reves soient plus longs que la nuit."

steve@taumet.com (Stephen Clamage) (02/10/91)

BRL102@psuvm.psu.edu (Ben Liblit) writes:

>I want to initialize an array [statically] with values that are constant,
>but are in the form of expressions.  For example,

>   double  value[ 2 ] = { sqrt( 2 ) / 2, cos ( sqrt( 5 ) ) };

>Is there any way to accomplish this?

In C, static initializers may not contain function calls.  sqrt and cos
are part of the run-time library, not built-in to the language.

C++, however, allows general expressions to initialize static variables.
The compiler collects non-constant expressions into a compiler-generated
initialization routine, then calls the routine before any user code in
the main program.  This is in fact run-time, rather than compile-time,
initialization, but it allows the convenient notation you want.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

dsebbo@dahlia.uwaterloo.ca (David Ebbo) (02/11/91)

In article <91039.144030BRL102@psuvm.psu.edu> BRL102@psuvm.psu.edu (Ben Liblit) writes:
>I want to initialize an array with values that are constant, but are in the
>form of expressions.  For example,
>
>   double  value[ 2 ] = { sqrt( 2 ) / 2, cos ( sqrt( 5 ) ) };
>
>Is there any way to accomplish this?  I know I could do this in some sort of
>'for' loop, or else by assigning values explicitly.  I'd really like to avoid
>this, though, as having the initialization in the declaration area would be much
>more readable.  The example above is a simplification -- the actual arrays are
>quite large and explicit, individual assignment would be too cluttering.
>
>Is there *any* way to convince my compiler (High C Compiler version 2, off of a
>Unix box) to give me this sort of initialization within the declaration area?
>

I think that the answer is no.  To be able to use initialization, the values
have to be known at compile time, which is not the case if you are calling
functions.

Why don't you compute the values 'by hand' first, and then put them all in a
header file of #define statements?  Well, if you have a lot of them,  it might
not be a great idea :-)

fenn@wpi.WPI.EDU (Brian Fennell) (02/12/91)

In article <1991Feb11.005518.3989@watdragon.waterloo.edu> 
	dsebbo@dahlia.uwaterloo.ca (David Ebbo) writes:
>In article <91039.144030BRL102@psuvm.psu.edu> 
>	BRL102@psuvm.psu.edu (Ben Liblit) writes:
>>I want to initialize an array with values that are constant, but are in the
>>form of expressions.  For example,
>>
>>   double  value[ 2 ] = { sqrt( 2 ) / 2, cos ( sqrt( 5 ) ) };
>
>I think that the answer is no.  To be able to use initialization, the values

Althogh I would have to aggree that the answer is no to your specific
question I suggest something like this.

---------------makeconsts.c--------------
#include <math.h>
#include <stdio.h>

#define CONNOTOPEN	1	/* non zero for errors */
#define	GOOD		0	/* zero for everything-fine */

#define _		fprintf
#define begin 		_(F,"\n\t{\n\t")
#define element(d) 	_(F,"%21G",(double)(d));
#define comma		_(F,"\t , \n\t")
#define end 		_(F,"\n\t} ;\n\n")


static char CONSTDATA[]="./constdata.h"
FILE	*F;

main(argc,argv) int argc;  char *argv[];
{
  if ( ! (F = fopen(CONSTDATA,"w")) ) {
    printf("%s: Cannot Open %s\n",argv[0],CONSTDATA);
    exit( CANNOTOPEN );
  }

  _(F,"	/*********************************************\\      	\n");
  _(F,"	  %s created by %s.c  \n",CONSTDATA,argv[0]);
  _(F,"	                  D O   N O T                       	\n");
  _(F,"	   C H A N G E   T H I S   B Y   H A N D !          	\n");
  _(F,"	\\*********************************************/ 	\n");
  _(F,"\n\n");

  _(F,"static double  value[]="		); 	open;
  element( sqrt( 2 ) / 2 		); 	comma;
  element( cos ( sqrt( 5 ) )		); 	end;

/*
	.
  	.
  	.
*/

exit (GOOD);
}

---------Makefile--------------
all: myprog


makeconsts.o: makeconsts.c


makeconsts: makeconsts.o
	cc -o makeconsts makeconsts.o -lm

constdata.h: makeconsts
	makeconsts

myprog: myprog.o constdata.h
	cc -o myprog myprog.o -lm

dave@aspect.UUCP (Dave Corcoran) (02/12/91)

In article <91039.144030BRL102@psuvm.psu.edu>, BRL102@psuvm.psu.edu (Ben Liblit) writes:
> I want to initialize an array with values that are constant, but are in the
> form of expressions.  For example,
> 
>    double  value[ 2 ] = { sqrt( 2 ) / 2, cos ( sqrt( 5 ) ) };
> 
> Is there *any* way to convince my compiler (High C Compiler version 2, off of a

Well you said "any":
define(`bc_',`syscmd(echo "$'`1"| bc -l)')

double val[] = { bc_(sqrt(2) / 2), bc_(c(sqrt(5)))};
                                       ^^^^^^^^^^ ---- any valid bc(1) expr 
                                                       without commas
                                                       (they are interpreted
                                                       by m4 as arg separators)


I use trailing underscores to denote m4 macros.

This is as slow as mollasses through a funnel in January though.
-- 
David Corcoran		      -@@
uunet!aspect!dave	        ~
In a society where anything goes eventually everything will.

dave@aspect.UUCP (Dave Corcoran) (02/20/91)

In article <91039.144030BRL102@psuvm.psu.edu>, BRL102@psuvm.psu.edu (Ben Liblit) writes:
> I want to initialize an array with values that are constant, but are in the
> form of expressions.  For example,
> 
>    double  value[ 2 ] = { sqrt( 2 ) / 2, cos ( sqrt( 5 ) ) };
> 
> Is there any way to accomplish this?  I know I could do this in some sort of
> 

I tried mailing but it bounced.

I have been toying with the idea of obtaining a better C preprocessor,
something that would allow fairly complex manipulations of text, something
akin to an macro assembler. The marriage of m4 and perl seem to give me what
I want, though a little ugly.

include file: perlm.m
-----------------8<----------------------
define(`pe_',
	`syscmd(perl -e ' '`
	$@
	''`
)')
-----------------8<----------------------


source file: tst.c.m
-----------------8<----------------------
include(perlm.m)


/* use any perl script to generate numbers */
double x [] = {pe_(
	for $i (1..5) {
		$out=join(",",$out,cos($i),log($i));
	}
	($out=~s/,//); # note the parens; needed to overide comma
                       # as m4 arg separator
	print $out;
	)};

/* create 2 new macros in terms of perl macro */
define(cs_,`pe_(printf ("%2.2f,%2.2f",sin(cos($1)),cos($2));)')
/*                     ^--- note parens again ------------^ */

define(x,`pe_(print cos($1);)')

/* invoke them */
double y [] = {cs_(1,4),x(22)};
-----------------8<----------------------
-- 
David Corcoran		      -@@
uunet!aspect!dave	        ~
In a society where anything goes eventually everything will.