Why does C hate 2d arrays?

brnstnd at stealth.acf.nyu.edu brnstnd at stealth.acf.nyu.edu
Mon May 28 06:09:06 AEST 1990


In article <N.O32W6 at xds13.ferranti.com> peter at ficc.ferranti.com (Peter da Silva) writes:
> In article <12923:May2502:17:3090 at stealth.acf.nyu.edu> brnstnd at stealth.acf.nyu.edu (Dan Bernstein) writes:
> > In article <K3O3WK1 at xds13.ferranti.com> peter at ficc.ferranti.com (Peter da Silva) writes:
> > > [assume: array[m][n] works for m and n not constants]
> > > What possible advantage would there be to requiring that m and n not
> > > change value while array is in scope?
> > The compiler isn't *forced* to make extra, possibly unnecessary, copies
> > of m and n.
> The compiler is not forced to make extra copies of m and n either way. Only
> if they're found to have changed.

How do you expect it to figure that out? And once m and n do change,
where do you think it's going to store the original values? Why not let
the programmer have control over those values?

> struct _point { int x, y };
> foo(box) struct point box[2]; {
> 	char tmp[box[1].x - box[0].x][box[1].y - box[0].y];
> 	bar(box, tmp); print(box, tmp); }
> How do you guarantee that box is constant? In general, you can't.

Q requires that array dimensions be const (i.e., unvarying within their
scope, lifetime, whatever). Given box declared const, the answer is
``yes, you can.'' const filters down through function invocations: if
bar were to change box, then it couldn't declare box constant in the
function declaration, so bar(box,tmp) (rather, bar(&box,&tmp), because Q
treats arrays differently) wouldn't be valid.

This all makes perfect sense. What are you objecting to?

> > Do you agree that, given this scenario, it's better for the programmer
> > to have access to C's value than not?
> How do you feel about:
> 	char *a = malloc(some_expression);
> How does this materially differ from:
> 	char a[some experssion];
> in the context of this discussion?
> Do you agree that, given this scenario, it's better for the programmer to
> have access to !some expression!'s value than not? Whether you're mallocing
> or not.

No. In the malloc() case, the expression is evaluated at one particular
moment, and the dimension isn't carried in the type (which is just
``pointer to char''). In the array case, the type of the array (``array
size some_expression of character'') includes the dimension, and that
dimension had better be constant.

Given that we *have* to carry around a constant value for the array type
to work, it's better for the programmer to have access to that value.
The premise isn't true for malloc().

On the other hand, if you wanted to have a as a pointer to a malloc()ed
array of that length, then you'd write char (*a)[some_expression] = ...
and then it would be part of the type.

(Side note: There's a separate issue from array type checking here,
namely pointer bounds checking. A pointer to char is really a pointer to
chars within an object consisting of an array of chars, and to check the
validity of pointer use you have to know the lower bound and size of
that array. I'm still working on this problem; for the moment, Q has a
couple of noop type qualifiers specifying those bounds.)

> It may be good programming practice, but this is C, not Pascal. C is expected
> to bend over backwards to do weird stuff that flakey programmers might want
> to do.

Why don't you give an example where requiring the dimensions to be
const restricts the programmer? I see it as more flexible.

---Dan



More information about the Comp.lang.c mailing list