Code Smell 225 - Pass by Reference
Tags: webdev, beginners, programming, tutorial
Published: 2023-09-25 23:57:04

*Pass by copy, pass by reference. which is better?*

> TL;DR: Beware of passing arguments by reference

# Problems

- Unexpected Results

- Side Effects

- Readability

- Broken Encapsulation

# Solutions

1. Pass arguments by copying even large objects. Don't make [premature optimizations](https://dev.to/mcsee/code-smell-20-premature-optimization-4moe).

2. Declare variables as [constants](https://dev.to/mcsee/code-smell-116-variables-declared-with-var-5mj)

3. [Refactor](https://methodpoet.com/modifying-method-parameter/) the code

4. Make objects [immutable](https://dev.to/mcsee/code-smell-176-changes-in-essence-5265) to avoid accidental changes

5 Use Pure Functions

# Context

A call-by-reference language like C# or PHP makes it more difficult for a programmer to track the effects of a function call, and may introduce subtle bugs.

This is a very old technique present in low-level languages to favor performance and avoid the cost of copying large structures. 

Some languages like Go use *pass-by-value* semantics. 

When you pass arguments to a function, copies are made. 

However, when you pass a pointer to an object, you can modify the original object within the function. This is another code smell.

On the contrary, functional languages forbid this mechanism completely. 

# Sample Code

## Wrong

[Gist Url]: # (https://gist.github.com/mcsee/5f444e26b2b3a658004a8c39ef5f30a1)
```csharp
using System;
 
namespace Example
{
     class Betelgeuse
     {
         static void Main(string[] args)
         {
             double starSize = 100.0;
             Console.WriteLine("star size: {0}", starSize);
             // star size: 100
             double supernovaSize = SimulateFinalSize(ref starSize);
             // Notice 'ref' modifier
             Console.WriteLine("supernova size: {0}", supernovaSize); 
             // supernova size: 10000
             Console.WriteLine("original star size after: {0}", starSize);
             // original star size after: 10000
             // WRONG: It should not be affected
         }
         public static double SimulateFinalSize(ref double size)
         {
             // Notice 'ref' modifier
             // Oversimplification
             // You should use Sedov-Taylor solution
              size = size * 100;
              return size;
         }
     }
}
```

## Right

[Gist Url]: # (https://gist.github.com/mcsee/8e19291a5de8ad1b7a7ebf30ab0935f0)
```csharp
using System;
 
namespace Example
{
     class Betelgeuse
     {
         static void Main(string[] args)
         {
             const double starSize = 100.0; 
             // The const modifier warns the compiler
             Console.WriteLine("star size: {0}", starSize);
             // star size: 100
             double supernovaSize = SimulateFinalSize(starSize);
             // Notice 'ref' is omitted
             Console.WriteLine("supernova size: {0}", supernovaSize);
             // supernova size: 10000
             Console.WriteLine("original star size after: {0}", starSize);
             // original star size after: 100
             // It remains at the original value
         }
         public static double SimulateFinalSize(double size)
         {
             // Notice 'ref' is omitted
             // Oversimplification
             // You should use Sedov-Taylor solution
              size = size * 100;
              return size;
         }
     }
}
```

# Detection

[X] Semi-Automatic 

You can use many linters to warn with arguments passed by reference

# Tags

- Readability

# Conclusion

Passing objects by reference can lead to unexpected side effects if the function modifies the object in a way that wasn't anticipated by the caller. 

You should use copy by value instead.

# Relations

{% post https://dev.to/mcsee/code-smell-116-variables-declared-with-var-5mj %}

{% post https://dev.to/mcsee/code-smell-176-changes-in-essence-5265 %}

{% post https://dev.to/mcsee/code-smell-209-side-effects-13l8 %}

# More Info

[Modifiyng Method Parameter](https://methodpoet.com/modifying-method-parameter/)

[Wikipedia](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_reference)

# Disclaimer

Code Smells are my [opinion](https://dev.to/mcsee/i-wrote-more-than-90-articles-on-2021-here-is-what-i-learned-1n3a).

# Credits

Photo by [Quino Al](https://unsplash.com/@quinoal) on [Unsplash](https://unsplash.com/photos/KydWCDJe9s0)
    
* * *

> Make it correct, make it clear, make it concise, make it fast. In that order.

_Wes Dyer_

{% post https://dev.to/mcsee/software-engineering-great-quotes-26ci %}

* * *

This article is part of the CodeSmell Series.

{% post https://dev.to/mcsee/how-to-find-the-stinky-parts-of-your-code-1dbc %}