[net.lang.c] multidimensional arrays

breuel@harvard.ARPA (Thomas M. Breuel) (01/06/85)

|[Doug Gwyn@Brl-Vld.ARPA writes:]
|I love C and use it for almost all applications programming.
|The single biggest deficiency I have found in the language
|is what Mr. Grady explained:  Formal array parameters are
|not permitted to have parametric dimensions.  That is,
|
|void mat_mul( p, q, r, a, b, c )
|	int	p, q, r;	/* dimensions */
|	double	a[p][q], b[q][r], c[p][r];	/* arrays */
|	{
|
|is not a legal C procedure header.  It is clear that a C
|compiler COULD be made to handle this more general case,
|and that there is no practical way to code this procedure
|using the current language definition.  If one wants to
|displace Fortran from its dominating position in numerical
|software, this problem HAS to be solved.

I don't have any FORTRAN reference handy, but as far as I re-call, many
(all?) FORTRANs do not permit functions of the above kind either.

If you need functions of the above kind, you can help yourself by using
vectors as two-dimensional arrays and providing macros for creation and
accessing them. Alternatively, you can rely on the compiler's
representation of two-dimensional arrays in memory and only provide
access functions.

BTW, who wants to displace FORTRAN from its dominating position in
numerical computing? And why would you want to replace it with 'C'?
'C' is not very suited to numerical applications anyhow; the automatic
promotion of float to double, and the lack of handling
of over- and underflow are some of the problems. (Flames to me -- I
love flames. Don't clutter the net with them).

						Thomas.
						breuel@harvard.

gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (01/07/85)

> |void mat_mul( p, q, r, a, b, c )
> |	int	p, q, r;	/* dimensions */
> |	double	a[p][q], b[q][r], c[p][r];	/* arrays */
> |	{
> 
> I don't have any FORTRAN reference handy, but as far as I re-call, many
> (all?) FORTRANs do not permit functions of the above kind either.

You recall incorrectly.  Procedures like the above are legal in ANS `66
FORTRAN and Fortran `77, and are heavily used.

> If you need functions of the above kind, you can help yourself by using
> vectors as two-dimensional arrays and providing macros for creation and
> accessing them. Alternatively, you can rely on the compiler's
> representation of two-dimensional arrays in memory and only provide
> access functions.

If you have ever tried this you would know how gross it really is.
What is the point of a compiler if one has to resort to awkward
kludges to specify perfectly normal operations?

> BTW, who wants to displace FORTRAN from its dominating position in
> numerical computing? And why would you want to replace it with 'C'?
> 'C' is not very suited to numerical applications anyhow; the automatic
> promotion of float to double, and the lack of handling
> of over- and underflow are some of the problems.

FORTRAN is an atrocious language by modern standards.  C, while not
perfect, is much better for writing reliable production code.  It
would be better to use a single language for applications instead of
two (or worse, a combination of the two).

(My Fortran experience dates back to around 1960, but I wouldn't choose
to use it for any application now!)

ANSI standard C is expected to solve the problem of all arithmetic being
done in double precision, which I don't think was much of a problem.
FORTRAN does not handle overflow or underflow either, and any code that
has problems in this regard was not carefully written.  (Does anyone
remember scaled fixed point?  Worked just dandy..)

dgary@ecsvax.UUCP (D Gary Grady) (01/07/85)

<>
A couple of posters (and a few correspondents) have questioned whether
FORTRAN permits variably-dimensioned array parameters.  That is, does
this always work in FORTRAN:

SUBROUTINE FOO(ARRAY, R, C)
DIMENSION ARRAY(R, C)

The answer is yes, it works in all correct FORTRAN compilers.  It is a
standard feature of the language.  It is true that the UCSD p-System
FORTRAN doesn't allow that, even though its documentation used to say
otherwise.  This is because the UCSD p-System FORTRAN compiler stinks.
What can I say?

BTW, this also works in virtually all FORTRANs with array bounds
checking turned off:

SUBROUTINE FOO(ARRAY, R)
DIMENSION ARRAY(R, 1)

Because FORTRAN stores column-major and hence does not need to know the
last dimension to perform a subscript calculation.  Many, many FORTRAN
programs do this, even though its "legality" is open to question.

Best,

-- 

D Gary Grady
Duke University Computation Center, Durham, NC  27706
(919) 684-4146
USENET:  {decvax,ihnp4,akgua,etc.}!mcnc!ecsvax!dgary

cottrell@nbs-vms.ARPA (01/11/85)

/*
okay, so you want to specify the dimensions at runtime? try this:

#define	ROWS	some constant
#define COLS	some constant

int a[ROWS][COLS];

main()
{	func(a,3,5);
	func(a,6,4);
}

#define	A(x,y)	*(a + x*j + y)

func(a,i,j)
int a[1];
{	int p,q;
	for (p = 0; p < i; p++) 
	for (p = 0; p < i; p++) {	/* row loop */
		for (q = 0; q < j; q++){/* col loop */
			printf("%d\t",A(p,q));
		} printf("\n");
	}
}

see if that doesn't get you two dimensions for one. the only problem is
that the address of an array element cannot be taken. to do that you need:

#define A(x,y) a[x*j + y]

hey, why didn't i just say that in the first place?
*/

msb@lsuc.UUCP (Mark Brader) (01/19/85)

> int a[ROWS][COLS];
> #define	A(x,y)	*(a + x*j + y)
> func(a,i,j)
> int a[1];
> ....
> 			printf("%d\t",A(p,q));
> ... the only problem is
> that the address of an array element cannot be taken. to do that you need:
> 
> #define A(x,y) a[x*j + y]
> 
> hey, why didn't i just say that in the first place?

Really now, you might have tried it.  (Yes, I did.)  Of course the two are
equivalent.   By the way, wouldn't it be clearer to declare int a[]; without 1?

Mark Brader