Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing containers by value or by reference

I am aware of the differences between pass by value, reference or pointer in the general case. However, my question is about special case about a container with simple structure.

Assuming this case:

class image{
    image()=default;
    image(image const&)=default;
    ~image()=default;

    int w;
    int h;
    uchar* data;
}

When passing an object of this class what copied are just two integers and pointer not the whole data. In this case is there purpose to passing it by reference ? Or is there a purpose to not passing it by reference?

The thing that triggered this question is that I have read that iterators in C++ were designed to be light and to be passed by value. So, I think that this concept may be applied to classes that represent a container to actual data no a data.

like image 203
Humam Helfawi Avatar asked Jan 27 '16 08:01

Humam Helfawi


People also ask

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.

Which is better pass by value or pass by reference?

Pass-by-references is more efficient than pass-by-value, because it does not copy the arguments. The formal parameter is an alias for the argument. When the called function read or write the formal parameter, it is actually read or write the argument itself.

Is it faster to pass by reference or value?

As a rule of thumb, passing by reference or pointer is typically faster than passing by value, if the amount of data passed by value is larger than the size of a pointer.

Are STL containers passed by reference?

@BjörnPollex Yes! I forgot to mention that.


2 Answers

Imho, the best guidelines on how to pass arguments can be found in Herb Sutters excellent talk Back to the Basics! Essentials of Modern C++ Style. In your particular case, passing by value would be the best option, as your struct is cheap to copy.

cpp parameter passing overview.

like image 52
jupp0r Avatar answered Oct 10 '22 18:10

jupp0r


With the default copy constructor, any copy will be shallow and will not make a copy of the memory pointed to by data. So when you pass by reference, only the two integers and pointer will be passed, for a total of approximately 12 bytes (depending on your architecture, i.e. pointer size).

That difference is so small, that it does not really matter whether you pass it by value or by reference. The latter may be slightly faster because the pointer can probably always be passed in via a CPU register and the 12 bytes may not, but that is really micro-optimization.

Personally I pass anything but primitive types by (const) reference, by default, unless I have a reason not to (see jupp0r's answer). Major advantage during development is that as the class grows I don't have to worry about when it becomes too big and change all my functions to pass by reference.

As far as the default C++ iterators go: note that they are meant to basically be just pointers. In fact I know that for Microsoft Visual C++ compiling in Release mode with optimizations enabled, iterators for contiguous data structures such as std::vector will reduce to just that. I am not aware if other compilers do this as well, I would think so. However you will notice that if you disable optimizations, then suddenly there is a difference between writing it++ and ++it in loop increments, for example - purely because of the additional copy operation in the former case. So even "cheap to copy" may have an impact if you do it often enough. As usual: when worried about performance, measure and decide based on the numbers.

like image 40
CompuChip Avatar answered Oct 10 '22 17:10

CompuChip