doubt about passing values by address

J

johnnash

I saw this particular piece of code in a book which basically adds two
vectors and produces the sum


Vector *VectorAdd( Vector *a, Vector *b, Vector *c)

{

c->x = a->x + b->x ;

c->y = a->y + b->y ;

c->z = a->z + b->z;

return(c);
}


Now my doubt about this code is why did the author decide to return
the address of c ? Is it not true that when we pass values by
reference, then there is no need to return anything as changes are
automatically reflected at the address of the variable ?
 
M

Malcolm McLean

johnnash said:
I saw this particular piece of code in a book which basically adds two
vectors and produces the sum


Vector *VectorAdd( Vector *a, Vector *b, Vector *c)

{

c->x = a->x + b->x ;

c->y = a->y + b->y ;

c->z = a->z + b->z;

return(c);
}


Now my doubt about this code is why did the author decide to return
the address of c ? Is it not true that when we pass values by
reference, then there is no need to return anything as changes are
automatically reflected at the address of the variable ?
It's pretty pointless, because caller must already have the address of c.
However it helps to doucment that c is indeed the return vector.
 
F

fred.l.kleinschmidt

I saw this particular piece of code in a book which basically adds two
vectors and produces the sum

Vector *VectorAdd( Vector *a, Vector *b, Vector *c)

{

        c->x  =  a->x + b->x ;

        c->y  =  a->y + b->y ;

        c->z  =  a->z + b->z;

        return(c);

}

Now my doubt about this code is why did the author decide to return
the address of c ? Is it not true that when we pass values by
reference, then there is no need to return anything as changes are
automatically reflected at the address of the variable ?

This allows something like this:
VectorAdd( VectorAdd(&a,&b,&c), &d, &e );

to perform e=a+b+d
 
J

johnnash

This allows something like this:
VectorAdd( VectorAdd(&a,&b,&c), &d, &e );

to perform e=a+b+d

but still what is the point in returning address of e ?

we can directly retrieve the new value of e because the content has
been changed at the address. Isnt it true ?
 
L

Lew Pitcher

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I saw this particular piece of code in a book which basically adds two
vectors and produces the sum


Vector *VectorAdd( Vector *a, Vector *b, Vector *c)

{ [snip]
return(c);
}


Now my doubt about this code is why did the author decide to return
the address of c ?

The code author's intent is not evident from the code sample, so I can only
guess at his motivation. When I've written functions that return one of the
original arguments, I have made that design decision based on the potential
use of the function; that is to say, could the return value be used as an
argument to another function? The author of the VectorAdd function may have
had a similar thought, perhaps intending something like

void VectorPrint(Vector *a);
Vector *VectorAdd(Vector *a, Vector *b, Vector *c);
Vector *VectorDivide(Vector *a, Vector *b, Vector *c);
Vector vector[3];

VectorPrint(VectorAdd(vector+0,vector+1,vector+2));
VectorPrint(VectorDivide(vector+2,vector+0,vector+2));

Is it not true that when we pass values by reference,

In C, we /never/ pass values by reference. We /always/ pass values "by value".
In this case, the values being passed are pointers to Vectors.

But, I know what you meant ;-)
then there is no need to return anything as changes are
automatically reflected at the address of the variable ?

Poorly worded, and perhaps not what you meant. But sort of, yes.


- --
Lew Pitcher

Master Codewright & JOAT-in-training | Registered Linux User #112576
http://pitcher.digitalfreehold.ca/ | GPG public key available by request
- ---------- Slackware - Because I know what I'm doing. ------


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: Armoured with GnuPG

iD8DBQFHuvpzagVFX4UWr64RAgaPAKDHZa7xBxUl8ssrEMugjKjHRqhfKgCeLdlZ
WSnIP/R016ls2onTkdCBFz4=
=Olwd
-----END PGP SIGNATURE-----
 
B

Bartc

but still what is the point in returning address of e ?

Maybe to further allow:

VectorAdd(VectorAdd( VectorAdd(&a,&b,&c), &d, &e ), &f, &g);

etc.

Returning that address has little cost, which is more than offset by the
benefit of being able to use the result immediately, in the same expression.
Especially compared with vector arithmetic.

True, ultimately the very last VectorAdd would be returning a value for no
reason. If that worries you, create two versions of VectorAdd(), one
returning the address and one returning nothing.
 
D

Duncan Muirhead

but still what is the point in returning address of e ?

we can directly retrieve the new value of e because the content has
been changed at the address. Isnt it true ?

One can write slightly more succinct code this way. Of course
not everyone thinks brevity is a virtue.

One example is initialised variables
given vector* VectorAlloc( void); one could write, e.g.
Vector* c = VectorAdd( a, b, VectorAlloc());
Vector* e = VectorAdd( c, d, VectorAlloc());
... more declarations whose initialisers involve c,e..

If one just had void VectorAdd() one would have to write
Vector* c = VectorAlloc();
Vector* f = VectorAlloc();
... more declarations, but can't use c,e ..
VectorAdd( a, b, c);
VectorAdd( c, d, e);
... more code from the initialisers ...

Another example is nested function calls, e.g
VectorFree( VectorOp( P, VectorAdd( a, b, VectorAlloc())));
(where VectorOp() returns it's second argument).
 
P

Peter Nilsson

That is a good question because it's more common to see
the design matching a = b + c, returning a.

C only passes parameters and return values by value.
Pointers are used to emulate passing by reference.

Or perhaps more common...

SomeFunctionNeedingAVector(VectorAdd(&a, &b, &c));

More like e = (c = a + b) + d.
Maybe to further allow:

VectorAdd(VectorAdd( VectorAdd(&a,&b,&c), &d, &e ), &f, &g);

etc.

Fundamental point is that a function can only have one
signature. [If we forget about tgmath in C99.]
True, ultimately the very last VectorAdd would be
returning a value for no reason. If that worries you,

Get over it! ;-)
create two versions of VectorAdd(), one returning the
address and one returning nothing.

...and realise that no C programmer will thank you for
it. Indeed if asked to implement this, most C programmers
will shrug and simply do...

VoidVectorAdd(...)
{
/* ignore return value */
NonVoidVectorAdd(...);
}

Who wants to synchronously maintain two functions performing
the same task?
 
G

gw7rib

I saw this particular piece of code in a book which basically adds two
vectors and produces the sum

Vector *VectorAdd( Vector *a, Vector *b, Vector *c)

{

        c->x  =  a->x + b->x ;

        c->y  =  a->y + b->y ;

        c->z  =  a->z + b->z;

        return(c);

}

Now my doubt about this code is why did the author decide to return
the address of c ? Is it not true that when we pass values by
reference, then there is no need to return anything as changes are
automatically reflected at the address of the variable ?

As you've spotted, the function doesn't *need* to return the value of
c. But it does, so that the value is available if you want to use it.
Other people have given examples where using this return value allows
things to be written as a single line rather than as two lines.

It's similar to the situation with strcpy and strcat. Each of these
two functions returns one of its input parameters as its output. You
don't need to use this, but sometimes it is handy to.

Help that helps.
Paul.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top