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