[comp.unix.wizards] Implementation of alloca

dg@lakart.UUCP (David Goodenough) (06/10/88)

From article <16072@brl-adm.ARPA>, by enag@ifi.uio.no:
> This discussion on alloca at least gave me something to chew on.
> I'm concerned with the implementation of a declaration like this, and
> the associated code:
> 
> 	kaflunk(n, m)
> 	int n, m;
> 	{
> 		int array[n];
> 		int matrix[n][m];
> 		long something;
> 	}
> 
> array is easy:  make it a pointer, and allocate memory for it (by this
> stack allocation feature, or malloc, or something more ingenious), and
> use it transparently.
> 
> matrix is worse: of course, it is still a pointer, and memory is
> allocated, but you need to hold the size of all but the first dimension
> to make the access algorithm work right.

I would suggest the following:

	int **matrix;
	int i;

	matrix = alloca(n * sizeof(int *));
	for (i = 0; i < n; i++)
	    matrix[i] = alloca(m * sizeof(int));

Now accessing matrix APPEARS to be normal: matrix[foo][blurf] will work,
althought the internals of the code generated will be different. Whatever
the case using a memory allocator for a multidimensional array is never
too pretty. However, in my humble opinion, I would rather get the messy
part out of the way when things are set up, and then have useages look
normal.
-- 
	dg@lakart.UUCP - David Goodenough		+---+
							| +-+-+
	....... !harvard!cca!lakart!dg			+-+-+ |
						  	  +---+

allbery@ncoast.UUCP (Brandon S. Allbery) (06/18/88)

As quoted from <16072@brl-adm.ARPA> by enag@ifi.uio.no on dynamic arrays:
+---------------
| Doesn't this look very clumsy to do in such a neat language as C?
| Having to remember dimensions and their individual sizes (even opening
| up for bounds checking - shock horror! :-), and building nasty access
| poly(g)nomes requiring lots of CPU time even for tiny little two-
| dimensional matrices...  It sounds Wrong to me.  Also, the bugs that
| will appear because people forget to pass along the dimensions of their
| conformant arrays -- leading all the way to sending a pointer to an
| array descriptor structure, slowing down all the code we're so proud
| of.
+---------------

Why not allocate matrix[n][m] by allocating an array[n], then set each element
to a pointer to an array[m]?  This makes the [] operator work exactly the way
it does everywhere else:  x[n] == *(x + n) without having to do hairy
calculations to access an element of an n-dimensional matrix.  No more likely
to have bounds checking than any other part of C.  ;-)

++Brandon
-- 
Brandon S. Allbery			  | "Given its constituency, the only
uunet!marque,sun!mandrill}!ncoast!allbery | thing I expect to be "open" about
Delphi: ALLBERY	       MCI Mail: BALLBERY | [the Open Software Foundation] is
comp.sources.misc: ncoast!sources-misc    | its mouth."  --John Gilmore

leo@philmds.UUCP (Leo de Wit) (06/19/88)

In article <155@lakart.UUCP> dg@lakart.UUCP (David Goodenough) writes:
=From article <16072@brl-adm.ARPA>, by enag@ifi.uio.no:
== This discussion on alloca at least gave me something to chew on.
== I'm concerned with the implementation of a declaration like this, and
== the associated code:
== 
== 	kaflunk(n, m)
== 	int n, m;
== 	{
== 		int array[n];
== 		int matrix[n][m];
== 		long something;
== 	}
  [stuff omitted]...
=I would suggest the following:
=
=	int **matrix;
=	int i;
=
=	matrix = alloca(n * sizeof(int *));
=	for (i = 0; i < n; i++)
=	    matrix[i] = alloca(m * sizeof(int));
=
=Now accessing matrix APPEARS to be normal: matrix[foo][blurf] will work,
=althought the internals of the code generated will be different. Whatever
=the case using a memory allocator for a multidimensional array is never
=too pretty. However, in my humble opinion, I would rather get the messy
=part out of the way when things are set up, and then have useages look
=normal.

And what about sizeof(matrix[0]) then ?  If it was a constant array,
this would yield a size of sizeof(int [m]) (fill in a m).  In the case
of an array of pointers, this would yield a size of sizeof(int *).  I
don't see how you can match the two with this scheme.

And what about matrix[2]++ ? Since matrix[2] is a pointer to int
perfectly allright. But not for a constant array, e.g.
int matrix[4][4]. Same goes for equation: matrix[1] = matrix[0].

And what about the following:

    int matrix[4][4], *sip, *dip;

    for (sip = matrix[1], dip = matrix[0]; sip < matrix[4]; *dip++ = *sip++) ;

to shift the rows of matrix one down. This is perfectly allright
because of the way the rows are stored in memory; also
memmove(matrix[1],matrix[0],3 * sizeof(matrix[0])); is good (forget
about the typecasts). But for the alloca'ed array you get trouble.

Unless all quirks of the language are completely compatible, I think it
is dangerous to hide these things from the programmer. If you like
dynamic arrays be put into C the compiler should generate appropriate
code (it can also check things better); don't think a int * is the same
as an int [] although the value may be (but I think you knew that already).

    Leo.