Why does C hate 2d arrays?

brnstnd at stealth.acf.nyu.edu brnstnd at stealth.acf.nyu.edu
Wed May 30 09:57:02 AEST 1990


In article <3066 at goanna.cs.rmit.oz.au> ok at goanna.cs.rmit.oz.au (Richard A. O'Keefe) writes:
> In article <12722:May2501:41:2690 at stealth.acf.nyu.edu>,
>  brnstnd at stealth.acf.nyu.edu writes:
> > I've tried to shorten this article by replacing flames with the phrase
> > 'Nuff said.
> That's more incendiary than most flames.

Quite right, and I apologize. I was in a bad mood.

As for whether Ada can work with any other language: I accept your
criterion that ``working with'' language X means that ``applications
programmers could call either language from the other, passing a useful
variety of data in either direction, even if not absolutely everything.''

I'm aware of one non-compliant Ada implementation that ``works with'' C,
but I don't know of any compliant implementations that do. You say that
they exist; given the restrictions on what an Ada environment has to be
like, I still find it very difficult to believe you. You could convince
me by very simply naming your evidence.

> > > > > In the presence of dynamic arrays, [whether sizeof X is legal in a
> > > > > static expression is] no longer a simple syntactic test.

By ``simple syntactic test'' I assumed you meant ``simple compile-time
test'': by far the most important issue here is what can be done well by
the compiler, and I thought you were sticking to that. Apparently you
weren't. My new response is ``Who cares? It's still an absolutely
trivial compile-time test.'' (As you admit, it isn't purely syntactic
[type-independent as well as value-independent] for straight C anyway.)

  [ dynamic own array ]

You're perverting the meaning of ``static'' in your example. In C, a
static variable can be allocated, with a fixed size, at compile time.
Dynamic own arrays just don't work that way. They're easy enough to set
up without pretending that they're static, so what's your problem?

> > Real computers have floating-point operations. 'Nuff said.
> Oh dear.  That means that the Sun-3/50 in my office is not a real computer.

Quite right.

> > > > > With specific reference to fwrite(), there are at least three fairly
> > > > > obvious possible complications which I'll not trouble you with.

I challenged you twice to name your ``obvious'' complications. You've
now failed to name them three times. I'd be surprised if you can answer,
because in my Q-to-C translator already supports dynamic arrays (which,
as Chris Torek pointed out many articles ago, are easy to implement),
with a perfectly consistent type structure. It has absolutely no trouble
working with fwrite(), because arrays are implemented as pointers.

> If someone _else_ would like to
> know what the problems are, ask, and I'll hand out the model answers.

Grow up.

> > > Here's another question about dynamic arrays.  Consider
> >   [ void f(int n) { double a[n]; int m = g(n); double b[m]; ... } ]
> > Better stated:
> >   void f(const int n)
> >   { double a[n]; int m; m = g(n); { const int x = m; { double b[x] ...
> That's not "better stated".  That's **RE**stated, as in CHANGED.
> There were two significant features about the way I formulated the
> question:  m was *NOT* const, and the declarations were in one group.

m is not const in the new version either, and the placement of
declarations into ``groups'' is for purely syntactic reasons. How are
these significant?

Are you complaining that b's dimension (which is now x, not m) is forced
to be const? That's how dynamic arrays work in Q. That's what scientific
programmers want for variable-sized arrays. How is this ``restriction''
significant?

Anyway, your question was how the compiler would allocate the arrays,
and neither of those ``significant features'' invalidates my answer.

    [ how things are allocated ]
> Yes, but *where* is b[] allocated?
  [ in straight C, offsets are known at compile time ]

I'd expect it to be allocated in the frame, though of course internal
behavior isn't standardized. Offsets not known at compile time do hurt
efficiency, and can seriously impair certain types of optimization; but
they're not fundamentally harder to compile.

> The simplest answer is to make dynamic arrays pointers,

There's no reason an implementation can't do that, and that's what q2c
does.

> However, a 'goto' leading out of a block
> gets complicated.

I agree. Q's implementation doesn't have gotos at the moment, partially
because I can't easily define their syntax or semantics, partially
because I've found no use for them given flexible breaks and exceptions,
and partially because I just haven't bothered. Anyway, if someone breaks
from a block that has something allocated, he'll typically go through a
break handler that deallocates the object. This applies to your example,
with the goto replaced by an appropriate break.

Your example of allocating an array[i] inside a switch(i) would be
handled the same way. (Though i would have to be const, and a smart
compiler might take advantage of this.)

> 	int m = f();
> 	int (*a)[m] = malloc(sizeof a);

Assuming m const... a is a pointer to an m-sized integer array. You're
initializing it to equal a pointer to an object of pointer size? What
are you trying to do here?

---Dan



More information about the Comp.lang.c mailing list