Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do C++ compilers optimize pass by const reference POD parameters into pass by copy?

Consider the following:

struct Point {double x; double y;};  double complexComputation(const& Point p1, const Point& p2) {     // p1 and p2 used frequently in computations } 

Do compilers optimize the pass-by-reference into pass-by-copy to prevent frequent dereferencing? In other words convert complexComputation into this:

double complexComputation(const& Point p1, const Point& p2) {     double x1 = p1.x; double x2 = p2.x;     double y1 = p1.y; double y2 = p2.y;     // x1, x2, y1, y2 stored in registers and used frequently in computations } 

Since Point is a POD, there can be no side effect by making a copy behind the caller's back, right?

If that's the case, then I can always just pass POD objects by const reference, no matter how small, and not have to worry about the optimal passing semantics. Right?

EDIT: I'm interested in the GCC compiler in particular. I guess I might have to write some test code and look at the ASM.

like image 606
Emile Cormier Avatar asked Jan 11 '10 18:01

Emile Cormier


People also ask

Does const get optimized?

The short answer is that const makes no difference to optimization; it's to help catch bugs at compile-time.

Should be passed by const reference pass by value?

Passing a parameter by const reference should be chosen where the semantics of references are actually required, or as a performance improvement only if the cost of potential aliasing would be outweighed by the expense of copying the parameter. At times, copying your parameters can also give you locality benefits.

Is it better to pass by reference?

2) For passing large sized arguments: If an argument is large, passing by reference (or pointer) is more efficient because only an address is really passed, not the entire object.

Why is it usually better to pass objects by reference than by value?

The reason is simple: if you passed by value, a copy of the object had to be made and, except for very small objects, this is always more expensive than passing a reference.


1 Answers

Your compiler can absolutely lift Point member variables into registers if needed. This, however, is not the same as the compiler converting the function call itself into pass by value.

You should inspect the generated assembly to see what optimizations are being done.

And FWIW, the general rule I use is to pass all primative types by value and all classes/UDTs (PODs or not) by const reference when I can, and let the compiler sort out the best thing to do. We shouldn't worry ourselves with the details of what the compiler is doing, it is much smarter than us.

like image 97
Terry Mahaffey Avatar answered Oct 13 '22 01:10

Terry Mahaffey