Thursday, December 4, 2014

Readability Snippet #1 : Pass by reference

When passing parameters by reference in C++ you basically have 2 options to do so:

Snippet #1: Pass the reference of the variable you want to pass to a function
Example:

 void foo(int& myIntParameter)  
 {  
   //... do something with myIntParameter  
 }  
 int main(int argc, char** argv)  
 {  
   int myIntVariable = 5;  
   foo(myIntVariable);  
 }  

Snippet #2: Pass the address of the variable you want to pass to a function
Example:

 void foo(int* myIntParameter)  
 {  
   if (myIntParameter)  
   {  
    //... do something with myIntParameter  
   }  
 }  
 int main(int argc, char** argv)  
 {  
   int myIntVariable = 5;  
   foo(&myIntVariable);  
 }  


Now, when reading code where variables get passed by reference like in snippet #1, it is actually not visible at first if the variable gets passed by value or passed by reference as the calling convention for both are actually the same. One had to look up the actual function definition by finding out whether the variable gets passed by reference or value. I consider this tedious as you always have to browse through your sourcecode to find out if a function call could *potentially* alter your variables value.

In this post, I'd like to present a way to make call by reference function calls more readable.

Snippet #3: Creating macro identifier for call by reference via actual variable reference

When using call by reference like in snippet #1, you could define some kind of macro qualifier that you can add to the function call.

Example:
 #define ref  
 void foo(int& myIntParameter)  
 {  
 }  
 int main(int argc, char** argv)  
 {  
   int myIntVariable = 5;  
   foo(ref myIntVariable);  
 }  

Unfortunately this has the disadvantage of not doing any compile-time checks.

------

Another solution would be to just don't use call by reference calls like in snippet #1 and just pass the address of the variable you want to modify. This method however usually introduces some sanity checks like null pointer checks etc. So you basically trade readability with compactness.