Why Pass Arguments By Value?

D

drmario

Last night I was reading a tutorial on writing C++ classes called "The ABCs
of Writing C++ Classes" at http://www.acm.org/crossroads/xrds1-4/ovp.html
About halfway down, in Guideline 8, he says:

Suppose we decided to derive a class Triangle from Shape:

class Triangle : public Shape {
public:
Triangle (const Point center,
const int color,
const Point v1,
const Point v2,
const Point v3);
private:
Point _v1, _v2, _v3;
};

I don't understand why these parameters are specified as value parameters.
Why would you want to pass in four Point values, and an integer, by value?
Now you will have extra memory taken up for the integer, as well as four
calls to Point's constructor AND extra memory for the instances of those
objects. Why not simply use reference parameters? Could someone explain to
me why you would EVER pass by value as opposed to const reference?

Thanks
Mario
 
C

Cory Nelson

Last night I was reading a tutorial on writing C++ classes called "The ABCs
of Writing C++ Classes" athttp://www.acm.org/crossroads/xrds1-4/ovp.html
About halfway down, in Guideline 8, he says:

Suppose we decided to derive a class Triangle from Shape:

class Triangle : public Shape {
public:
Triangle (const Point center,
const int color,
const Point v1,
const Point v2,
const Point v3);
private:
Point _v1, _v2, _v3;
};

I don't understand why these parameters are specified as value parameters.
Why would you want to pass in four Point values, and an integer, by value?
Now you will have extra memory taken up for the integer, as well as four
calls to Point's constructor AND extra memory for the instances of those
objects. Why not simply use reference parameters? Could someone explain to
me why you would EVER pass by value as opposed to const reference?

Thanks
Mario

In general if you don't want to modify a built-in type (such as int),
it will be faster to pass it by value. As for passing Points by value
(assuming they are an aggregate type), I don't know why he would do
that instead of a const reference.
 
P

Paavo Helde

Last night I was reading a tutorial on writing C++ classes called "The
ABCs of Writing C++ Classes" at
http://www.acm.org/crossroads/xrds1-4/ovp.html About halfway down, in
Guideline 8, he says:

Suppose we decided to derive a class Triangle from Shape:

class Triangle : public Shape {
public:
Triangle (const Point center,
const int color,
const Point v1,
const Point v2,
const Point v3);
private:
Point _v1, _v2, _v3;
};

I don't understand why these parameters are specified as value
parameters. Why would you want to pass in four Point values, and an
integer, by value? Now you will have extra memory taken up for the
integer, as well as four calls to Point's constructor AND extra memory
for the instances of those objects. Why not simply use reference
parameters? Could someone explain to me why you would EVER pass by
value as opposed to const reference?

Because this is simpler and faster?

I'm afraid you are not taking into account the fact that references are
usually implemented by pointers, each taking 8 bytes in current modern
hardware, plus one has to do indirect lookup through them when accessing
the values.

The guidelines say that small value objects with cheap constructors-
destructors should be sent by value. I guess Point is such an object,
though without seeing the definition one cannot be sure.

hth
Paavo
 
C

Christian Hackl

drmario said:
class Triangle : public Shape {
public:
Triangle (const Point center,
const int color,
const Point v1,
const Point v2,
const Point v3);
private:
Point _v1, _v2, _v3;
};

I don't understand why these parameters are specified as value parameters.
Why would you want to pass in four Point values, and an integer, by value?
Now you will have extra memory taken up for the integer, as well as four
calls to Point's constructor AND extra memory for the instances of those
objects.

References are usually implemented by pointers (although they don't have
to be), and pointers take up memory, too. Therefore, passing small
objects by value may actually be more efficient if those objects are
smaller than pointers.

FWIW, the Point parameters should probably be passed by (const) reference.
 
A

Andy Champ

Paavo said:
Because this is simpler and faster?

I'm afraid you are not taking into account the fact that references are
usually implemented by pointers, each taking 8 bytes in current modern
hardware, plus one has to do indirect lookup through them when accessing
the values.

The guidelines say that small value objects with cheap constructors-
destructors should be sent by value. I guess Point is such an object,
though without seeing the definition one cannot be sure.

hth
Paavo

Just to add to this - on Win64, to pick a platform not entirely at
random, and in is 32 bits and a reference is a 64-bit pointer. So int
is smaller. Point is probably two ints, so it's the same size as a pointer.

But I suspect the real reason is that the default is by value :)

Andy
 
J

Juha Nieminen

drmario said:
Could someone explain to
me why you would EVER pass by value as opposed to const reference?

Passing built-in types by value is more efficient than passing them by
const reference. This is probably also true for PODs with the size of a
built-in type, or even slightly larger. (How much larger the POD must be
before it becomes slower to pass by value depends on a lot of things and
in a particular platform this can only be determined by practical testing).
 
P

Paul Brettschneider

Juha said:
Passing built-in types by value is more efficient than passing them by
const reference. This is probably also true for PODs with the size of a
built-in type, or even slightly larger. (How much larger the POD must be
before it becomes slower to pass by value depends on a lot of things and
in a particular platform this can only be determined by practical
testing).

Matter of fact I just tried this and on x86 the reference version was
distinctly faster, on PA-RISC the copy version. Of course it might just be
g++ generating weird code for one of the cases.
 
A

Anand Hariharan

Why not simply use reference parameters? Could someone explain to
me why you would EVER pass by value as opposed to const reference?

Several folks have already said why built in types might be faster when
passed as value rather than const reference, so I won't go there.

Here is a case why you would pass by value:

Let's say in the implementation of a function, you actually need to modify
the input. It is not the objective of the function to return this
modified input back to the caller, but it needs to modify the input as a
part of its implementation.

Why would you have a signature of this function to accept a const
reference, only to make a copy of it in your function? Why not let your
caller pass it by value, and you play with it all you want?

- Anand
 
J

James Kanze

Because this is simpler and faster?

Because it is simpler, and corresponds to the desired semantics.
I'm afraid you are not taking into account the fact that
references are usually implemented by pointers, each taking 8
bytes in current modern hardware, plus one has to do indirect
lookup through them when accessing the values.
The guidelines say that small value objects with cheap
constructors- destructors should be sent by value. I guess
Point is such an object, though without seeing the definition
one cannot be sure.

The guidelines vary. In general, you have three possibilities:

-- by value, used when you want value semantics,
-- by reference, used when you want reference semantics, and
-- by const reference, used as an optimization measure, when
you want value semantics, but a copy is "expensive" (and in
special cases like the argument to the copy constructor,
which for obvious reasons cannot be by value).

Strictly speaking, given the above, you should probably only use
const reference when the profiler says you have to. In
practice, however, I'd say that most places have guidelines
suggesting const references as soon as you have a class type, or
perhaps a class type over a certain size, or with a user defined
copy constructor. Similarly, guidelines concerning templates
(where you don't know what the type will actually be like) vary.

I tend to use const reference for all class types, and always in
templates, not because it's "right", but because that
corresponds to the guidelines in the places I've worked. If you
look in the standard, however, you'll find it a lot less
consistent. (I suspect that the reason for pass by value in
many cases, e.g. iterators and functional objets, is that they
want the function to accept temporaries, but they also want to
be able to modify the value, and use non-const functions on it.)

The important thing is to have some consistent rule and stick to
it. Performance really isn't an issue most of the time (and
will often vary from one system to the next).
 

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,776
Messages
2,569,603
Members
45,216
Latest member
topweb3twitterchannels

Latest Threads

Top