Bartc said:
(...)
int f()[10];
(...)
foo() { int *a; ... { ... a = f(); ... } }
*a is a pointer to int. f() returns an array of int. So there is a type
mismatch and this should not compile, and the problem would not arise. I
don't think you can reasonably expect an array returned by a function to
'decay' to a pointer in the same way as a normal array.
No, I don't expect that - because the language forbinds "int f()[10]".
However, yes I do expect "a = <expression of type array of int>" to be
treated the same way regardless of where that expression comes from.
If it did not, just what should the program be allowed to do with it?
Well, it could be assigned to an array:
*a=f(); where a already points to a suitable space. Or possibly:
If you mean "int *a;", this is a type error (assigning an array to an
int) and I like compilers who warn me about that.
If a is declared as int (*a)[10], fine. That's just a case of allowing
array assignment. You can argue for or against that. Arguments against
is that it can be limited or confusing due to the normal "decay to
pointer" feature, and also that passing an array by value can be a much
huger operation than it looks like when you are used to that what
actually gets passerd is the pointer.
Same again.
Or it could be passed directly to another function that takes arrays
of the same size:
g(f());
That may require that the program first copies the array to a temporary
array in the caller's stack. So again, once it's there, what else is
the program allowed to do with the temporary? E.g.:
Would &f() be OK? *&f()? f()[0]? &f()[0]?
Another point - g(f()) would be an error if a prototype of g() was not
in scope. Then the compiler would not know that g() was expecting
an array rather than a pointer to the first element. So that answers
why it was not in K&R C - it did not have prototypes.
Current C does, but this feature would introduce another point where
calls with and without prototype would differ - and which could not
be fixed by casting the argument to the righe type.
Actually, adding such a new type of array wouldn't be that much of a
problem. But the special interaction between newarrays and pointers
wouldn't exist in the same way as for ordinary arrays.
They wouldn't anyway, due to the problem with g(f()) above. With
regular "decay-to-pointer" arrays, that call works fine with or without
a prototype for g.
Defining this in terms of how functions work is the wrong approach. It
makes things unnecessarily murky.
OTOH with such a non-decaying array type, we'd have that type clearly
spelling out the semantics of such array objects. Which is what types
are _for_. Jacob said he used operator overloading to make such an
array - and unless I misunderstood, what he made was a type.
So setting up dynamic arrays and indexing them as though they were fixed
arrays would not be possible.
I dunno. C99 supports variable-length arrays. But what you are
suggesting also seems to be passing fixed-length arrays around, so I
don't quite see your point.
So I don't see such newarrays being popular with C
aficionados. Especially as these arrays would have to be a fixed size
so would have the same limitations as early Pascal.
A new array type needs something extra, and that would need to be
flexible bounds, or bounds that are passed around with the array. But
then, this would be taking C to a slightly different level.
Yes. There are plenty of features it'd be nice to add to C. The
problem is to choose between them, and to find ten people who agree on
which features would be good and which would be bad. C99 was an attempt
at that, and has been less than successful so far.