On Tue, 11 May 2004 22:01:40 GMT, "Canonical Latin" <javaplus@hotmail.com>
wrote:[color=blue]
>
>Type checking and passing by value are two different issues. Consider:
>
>fun1 (T[]); // pointer-to-type-T[/color]
yes.
[color=blue]
>
>fun2 (T[2]); // array-of-size-2-of-type-T[/color]
Now, are you showing what you'd like it to be, or what you think is
actually being declared? As per all that's been said before, the type of
the parameter above is actually the same as the previous: pointer-to-T.
[color=blue]
>
>fun3 (T[3]); // array-of-size-3-of-type-T[/color]
again, just pointer-to-T.
[color=blue]
>
>fun4 (T**); // pointer-to-pointer-to-type-T[/color]
yes.
[color=blue]
>
>fun5 (T*[2]); // pointer-to-array-of-size-2-of-type-T[/color]
Nope, just pointer-to-pointer-to-T.
[color=blue]
>
>fun6 (T*[3]); // pointer-to-array-of-size-3-of-type-T[/color]
Still just pointer-to-pointer-to-T.
[color=blue]
>
>
>
>In none of the cases the whole array is passed by value and this is not the
>issue. Suppose that c++ actually did have a legitimate type
>array-of-size-N-of-type-T. Then
>
>fun (T x[]); // fun1
>
>fun (T x[2]); // fun2
>
>fun (T x[3]); // fun3
>
>main() {
>
> T a[2];
>
> T b[3];
>
> T c[4];
>
> T *d;
>
> fun(a); // call fun2
>
> fun(b) ; // call fun3
>
> fun(c) ; // call fun1 (see comment at end)
>
> fun(d) ; // call fun1[/color]
/IF/ C++ did as you'd like, then it would break all pre-existing code that
relies on the age-old behavior of arrays "decaying" to pointers. Imagine
requiring there to be an overload for each possible length N in cases such
as:
char string[N];
...
int i = strlen(string);
Would we want to have to have a separately compiled version of strlen for
each possible value of N? Or for strlen to be a template with a non-type
template parameter N? Yuck.
[color=blue]
>
>}
>
>Obviously this doesn't work in c++ because compiler sees
>array-of-size-N-of-type-T as pointer-to-type-T in most cases.[/color]
Remember that arrays retain their full type information as long as the
name they were declared with (as arrays) is still in scope and you use it.
That's why sizeof(array) works and &array actually yields a
pointer-to-array. But most of the things you do with arrays, such as
subscripting, end up with you losing that "array-ness" because it is no
longer needed by the resulting expression type. The fact this information
is also lost when using an array as a function argument is just an
occupational hazard of C/C++ programming. Check out today's thread with
subject "Copying struct with array" for some history as to why structure
assignment is allowed while array assignment is not; it's quite related to
this issue.
[color=blue]
> Enforcing type
>checking for arrays has nothing to do with passing the whole array by value.
>If you think my description of supposed behavior is too far fetched, or that
>arrays are just "smoke and mirror" then consider[/color]
It's not that I just /think/ they're smoke and mirrors, I know from having
implemented a C compiler by hand that native C/C++ arrays are essentially
nothing more than notational convenience (and extremely so in the case of
array function parameters). If you want object semantics for something
that works like an array, simply use a vector, or even boost::array if you
don't require dynamic resizing.
Every so often folks suggest how things "should" be in C or C++, and it
isn't that they aren't good ideas, but they're not good enough for the
chaos attempting to retro-fit them to the language /now/ would inevitably
cause. C++ is difficult enough to grok as it stands. I think the entire C++
community is only barely beginning to feel a bit of relief that compilers
in general have /almost/ caught up with the language as it was standardized
in 1998 (and only one family, the one based on the EDG front end, actually
has). Changes to the basic semantics of arrays just aren't going to happen.
[color=blue]
>
>void fun (T **x) { cout << "fun1"; }
>
>void fun (T (*x)[2]) { cout << "fun2"; }
>
>void fun (T (*x)[3]) { cout << "fun3"; }
>
>int main(int argc, char *argv[]) {
>
> T (*a)[2];
>
> T (*b)[3];
>
> T (*c)[4];
>
> T **d;
>
> fun(a); // call fun2
>
> fun(b) ; // call fun3
>
> fun((T**)(c)) ; // call fun1 (unsafe in c++)
>
> fun(d) ; // call fun1
>
>}
>
>which compiles and behaves as expected. Note that nothing is passed by
>value. What this is saying is that pointer-to-array-of-size-N-of-type-T is a
>different type for each value of N. What I am saying is that so far I have
>not heard a compelling reason why array-of-size-N-of-type-T should not also
>be a different type for each value of N.[/color]
As I said above, even if this would be an overall improvement to the
language (and I'm not saying it would be; I haven't completely thought it
through, and I'm not likely to), it would no longer be C or C++ and thus
could not possibly be worth breaking most of the existing C/C++ code base
to effect.
Note that using boost::array, you can achieve the overloading you want,
retain full performance of native arrays, and still "pass" arrays as
efficiently as C/C++ doesn't (just pass by reference).
[color=blue]
>
>
>
>Another issue that is closely related to this: There is already a problem in
>c++ with type pointer-to-array-of-size-N-of-type-T which I marked as
> "unsafe" in my example. Essentially you cannot convert
>pointer-to-array-of-size-N-of-type-T to pointer-to-pointer-of-type-T without
>using a reinterpret cast. This perhaps is the source of the odd behavior of
>reinterpreting array-of-size-N-of-type-T as pointer-to-type-T. Of course,
>this whole business would go away (and we get true typed arrays in bargain)
>if array-of-size-N-of-type-T is automatically converted to pointer-to-type-T
>only if there is no matching type for the specific value of N.[/color]
Passing multi-dimensional arrays around takes some intestinal fortitude. It
always confuses the hell out of /me/, so I can't disagree about the
languages being weak in that regard. To make matters worse, there are no
wonderful replacements for multidimensional arrays in the modern C++ libs,
alas (at least none I've found yet.)
-leor
[color=blue]
>[/color]
--
Leor Zolman --- BD Software ---
www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html