Re: pass an array throuh a function
From: Leor Zolman (leor_at_bdsoft.com)
Date: 05/26/04
- Previous message: Gary Labowitz: "Re: Bug in my code or compiler?"
- In reply to: Chris \( Val \): "Re: pass an array throuh a function"
- Next in thread: Chris \( Val \): "Re: pass an array throuh a function"
- Reply: Chris \( Val \): "Re: pass an array throuh a function"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Wed, 26 May 2004 09:22:34 -0400
On Wed, 26 May 2004 19:37:55 +1000, "Chris \( Val \)"
<chrisval@bigpond.com.au> wrote:
>
>"Francis Glassborow" <francis@robinton.demon.co.uk> wrote in message
>news:sCh0OTEckFtAFwGe@robinton.demon.co.uk...
>| In message <cZQsc.114$%r.27073@nasal.pacific.net.au>, David White
>| <no@email.provided> writes
>| >It's not possible to pass an array to a function, at least not directly. If
>| >you try, only the address of the first element is passed, in other words
>| >a pointer.
>|
>| Not exactly true in C++. Consider:
>
>Ok, I'll bite ;-).
>
>| int const array_size(20);
>| typedef float data[array_size];
>|
>| void show(data & d){
>| for(int i(0); i != array_size; ++i){
>| std::cout << d[i] << " ";
>| }
>| )
>
>Doesn't this just demonstrate a way of using a reference
>to the pointer. You have still not passed the actual array
>though - just a pointer to it's first element as 'David'
>said, albeit this time by reference, no ?
I'll join in the bite-fest ;-)
This is an interesting point for me, "Mr. Newly Enlightened on What
References /Really/ Are" from a thread in days gone by around here. I
learned something then, and a bit more just now by toying with this issue.
So here's a version of Francis' test program (show1 is his version of show)
expanded to test your conjecture by adding versions of show() as follows:
show2 takes a reference to a non-const pointer-to-float
show2c takes a reference to a const pointer-to-float
show3 takes a vanilla pointer-to-float
#include <iostream>
#include <iomanip>
using std::cout;
using std::endl;
int const array_size(5);
typedef float data[array_size];
void show1(data & d) // Francis' version
{
cout << "in show1(), d = " << std::hex << d << endl;
for(int i(0); i != array_size; ++i){
std::cout << d[i] << " ";
}
cout << endl;
}
void show2(float * & d) // Chris's version
{
cout << "in show2(), d = " << std::hex << d << endl;
for(int i(0); i != array_size; ++i){
std::cout << d[i] << " ";
}
cout << endl;
}
void show2c(float * const& d) // Chris's with const
{
cout << "in show2(), d = " << std::hex << d << endl;
for(int i(0); i != array_size; ++i){
std::cout << d[i] << " ";
}
cout << endl;
}
void show3(float *d) // Leor's boring pointer version
{
cout << "in show3(), d = " << std::hex << d << endl;
for(int i(0); i != array_size; ++i){
std::cout << d[i] << " ";
}
cout << endl;
}
int main()
{
data x = {10, 20, 30, 40, 50};
float *fptr = x;
cout << "In main, x = " << std::hex << x << endl;
show1(x); // OK, ref to array
show2(x); // Error! Can't convert 'data' to float *&
show2(fptr); // OK, CAN have ref to a "real" float *
show2c(x); // OK, ref to const float *
show3(x); // OK, ptr to float
return 0;
}
show1 just does things the way they were before, and of course, works.
show2 is set up as the version you suggested below, and does not compile.
How can you have a reference to a pointer that doesn't actually "exist"?
IOW, this is where the "reference-ness" of the parameter really stands out.
There's no actual non-const pointer to bind that parameter to. You can't
expect to, say, delete and then re-assign the pointer (as you describe),
when there's no actual pointer to assign to. This actually makes sense to
me, which is scary ;-)
If you call show2 passing an actual, honest-to-goodness float *, however
(as shown when I pass fptr), it compiles fine. Now the parameter can be
bound to a non-const pointer-to-float directly.
In the case of show2c, adding the const qualifier makes it possible for the
compiler to generate a temporary pointer to the first element of the array
and then have the function parameter be bound to it (I think...). So here,
presumably, you /could/ call delete on that pointer (although it would be
UB in this particular case, since the address wasn't obtained from new),
but you still could not, of course, assign the result of a new expression
to the pointer (since temporaries are const).
Finally, you can call show3 the same way you call show1, by passing x
"directly"; in the case of show3, the array name decays to a pointer in
old-fashioned C-style.
What a way to start the day, esp. after only 3.5 hours sleep ;-)
-leor
>void show( float*& d )
> {
> // ...
> }
>
>Passing by reference in this way, would of course allow
>us to delete the memory, and then re'new' the array within
>the function to an alternate size, but we are always only
>working with the pointer, no matter if it is passed by value
>or reference aren't we ?
>
>| However what you cannot do is to pass an array by value
>| unless you wrap it up in a class or struct.
>
>I thought this held true for arrays no matter what type of
>passing idiom we chose ?
>
>Cheers.
>Chris Val
>
-- 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
- Previous message: Gary Labowitz: "Re: Bug in my code or compiler?"
- In reply to: Chris \( Val \): "Re: pass an array throuh a function"
- Next in thread: Chris \( Val \): "Re: pass an array throuh a function"
- Reply: Chris \( Val \): "Re: pass an array throuh a function"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|