views:

352

answers:

3

Two questions rolled into one here...

I have a number of functions which are called multiple times per frame for a real-time video processing application. Taking advice about const and pass by reference, the functions have a signature somewhat like this

void processSomething(const int& value);

As I keep typing the few extra characters, I am wondering if this is overkill.

Second question, well, on the subject of pass by reference, within the slots/signals mechanism of QT, does pass by reference helps to prevent copying of objects as in a normal function call?

+6  A: 

Yes, pass by reference helps against copying the objects. But the compiler might decide to optimize it out entirely and insted pass by value if it produces the same effect. Such optimization is usually possible if the function and the call site are in the same translation unit but some compilers can do even more global optimizations - you can inspect the emitted assembly if you care.

This is why you really shouldn't pass primitive types by reference if you care about performance and unless you really have reasons for that. See http://stackoverflow.com/questions/672700/what-is-the-use-of-passing-const-references-to-primitive-types for discussion of that problem.

sharptooth
The only situation in which the compiler could do this optimization, though, is if the caller and the callee are in the same translation unit.
Martin B
Actually, no, and Visual C++ proves it. They call it Link-Time Code Generation. ISO C++ doesn't specify the exact responsibilities of the preprocessor, compiler, linker and runtime.
MSalters
+11  A: 

Yes, this is overkill and will actually result in slower code than if you passed the int by value. An int is four bytes; a reference (essentially a memory address) is either also four bytes (on a 32-bit machine) or eight bytes (on a 64-bit machine). So you may actually need to pass more information to the function -- and additionally, you have the overhead of dereferencing that reference.

If you're passing something bigger than an int, however, it's more efficient to use a const reference, because you can pass just four or eight bytes instead of having to copy the whole object.

Edit Regarding Qt: Yes, if the slot takes a const reference to an object, then the reason for that is to save the overhead of copying the object.

Martin B
+3  A: 

First - the difference between

  • void processSomething(const int& value);
  • void processSomething(int value);

is: normally a const reference is passed by passing a pointer, the other thing is passed by copying. After the call (from the caller side) the result is equal. Whatever you pass to the function is not changed by the call.

Inside the function you won't see any differences either (at least on an int). On Objects, you may only use const functions of course.

On the performance side - passing a const reference to an int may (or may not) be slower, depending on compiler and optimization. The compiler could (in theory) optimize the passing of the const reference away to a pass by value, I don't know if it does though. Working with pointers to ints instead of values is slower of course.

For more information on that see: http://stackoverflow.com/questions/1327943/when-to-use-pointers-and-when-not-to-use-them/1328006#1328006


After reading the other linked post - the compiler can not optimize it away in a multithreaded environment. At least in a MT-environment there are real differences betwenn const int& and int calls. +1 for that link.

Tobias Langner
Actually, you can't use non-const functions on the `const int }` is illegal but `processSomething(int value) { foo(value); }` is legal.
MSalters