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;
}