Fire Lancer
Fire Lancer

Reputation: 30145

Should small simple structs be passed by const reference?

I have always been taught that non-primitive types should be passed by const reference rather than by value where possible, ie:

void foo(std::string str);//bad
void foo(const std::string &str);//good

But I was thinking today that maybe actually some simple user defined types may actually be better passed by value eg:

class Vector2
{
public:
    float x, y;
    ...constructors, operators overloads, utility methods, etc...
};

void foo(Vector2 pos);
void foo(const Vector2 &pos);//is this really better than by value?
void foo(float x, float y);//after all isn't by value effectively doing this?

My thought is that by passing the Vector2 by reference, it is actually more expensive than passing by value since the compiler is now using a pointer and dereferencing to access the const Vector2 &pos version?

Is this the case? Are simple objects best off passed by value? Where should the line be drawn?

Upvotes: 23

Views: 6908

Answers (6)

supercat
supercat

Reputation: 81247

One factor I've not seen mentioned is what the routine is going to do with the passed-in value. Unless the routine is expanded inline, manipulating data which are passed by reference will require more code than manipulating data which are passed by value. If the fields of the passed-in structure will on average be accessed less than once each, this extra overhead will be small compared with the overhead of copying the structure. If they will on average be accessed many times each, it would likely be better to have them on the stack. If the interface is already set as pass-by-reference for a structure which is heavily accessed, it may make sense for the called routine to copy all parts that are of interest. On the other hand, if the called routine is going to copy much or all of a structure anyway, it may as well be passed by value.

Upvotes: 2

rlduffy
rlduffy

Reputation: 618

An older, yet lucid, analysis of the ins-n-outs of passing parameters can be found at http://www.ddj.com/184403855. Of course c++0x obviates a lot of such issues with move semantics, but the paper provides a lot of justification for why move semantics are desirable.

Upvotes: 1

T.E.D.
T.E.D.

Reputation: 44804

Just as a matter of policy I pass any object that isn't a basic C data type by const reference. Its much easier to remember that way.

Upvotes: 3

a1ex07
a1ex07

Reputation: 37382

My thought is that by passing the Vector2 by reference, it is actually more expensive than passing by value since the compiler is now using a pointer and dereferencing to access the const Vector2 &pos version

It would be true if you passed an object where size_of(object) < size_of(pointer_to_object). For example, char const& might be more expensive than char

Upvotes: 0

Matt Davis
Matt Davis

Reputation: 46052

Passing by const reference avoids the construction of a new object. If your constructor is non-trivial, e.g., it allocates memory, you will be much better off passing by const reference than by value.

In the C# world, you make this decision by choosing whether to make something a class or a struct. Classes use reference semantics while structs use value semantics. Everything I've ever read says that you should generally choose to make everything a class unless it is very small, i.e., on the order of 16 bytes. If you are looking for a cut-off for when to pass by value versus const reference in C++, 16 bytes seems like a reasonable threshold.

Upvotes: 2

Peter G.
Peter G.

Reputation: 15144

Yes, simple objects should be passed by value. The line has to be drawn according to the architecture. If in doubt, profile.

Upvotes: 9

Related Questions