[comp.lang.c++] Variable constants

news@cit-vax.UUCP (03/13/87)

Organization : California Institute of Technology
Keywords: 
From: jon@oddhack.Caltech.Edu (Jon Leech)
Path: oddhack!jon

	While writing some C++ code which was intended to call FORTRAN
routines, I was using constant-dimensioned matrices. The logical thing
to do, then, was

	const int n = 20;
	double m[n][n];

	The FORTRAN routines wanted the matrix and the dimension of
the matrix passed, along with 6 other parameters. Initially I didn't
feel like templating the routine (pretty difficult to do correctly anyway, 
given that FORTRAN does not distinguish between array dimensions), so I 
just had:

	extern void foo(...);
	foo(m, &n, etc...);

	All fine and dandy. Now I decide to add a new array, declared
AFTER the subroutine call:

	double x[n];

	Oops! The enlightening error message 'error: cannot
evaluate constant' occurs. This was most confusing. After I bit I
decided this meant cfront thought that 'n' might be modified
within 'foo'. OK, so I proceeded to template the function:

	extern void foo(double m[n][n], const int *pc, etc...);

	Unfortunately, the same error message still occurred (this is
1.1, incidentally). I consider this a bug. The template is clearly
specifying that whatever is passed is not being modified, yet cfront
appears to believe this anyway. Perhaps Bjarne would care to
comment? ``Fixed in 1.2'', or must I work around it, or am I just
missing something obvious (it is 6:30 AM, after all)?

    -- Jon Leech (jon@csvax.caltech.edu || ...seismo!cit-vax!jon)
    Caltech Computer Science Graphics Group
    __@/

bs@alice.UUCP (03/15/87)

Jon Leech spotted this one:

	const int n = 20;
	double m[n][n];
	extern void foo(...);

	f() {
		foo(m, &n);
		double x[n];	// by now cfront has forgotten that n==20
		extern void fo(double m[n][n], const int *pc...);
	}

and comments "Perhaps Bjarne would care to comment? ``Fixed in 1.2''"
Unfortunately not, but here is a horrible hack that will allow cfront to
remember the value of integer constants after you have taken their address.
In expr2.c in expr::eval:

	case NAME:
	{	Pname n = (Pname)this; 
		if (n->n_evaluated && n->n_scope!=ARG) return n->n_val;
					// the following test is the fix:
		if (n->n_initializer
		&& n->n_initializer
		&& n->n_initializer->base==IVAL
		&& n->n_initializer->i1==n->n_val) return n->n_val;
		if (binary_val && strcmp(string,"_result")==0) return 8888;
		Neval = "cannot evaluate constant";
		return 1;
	}