DEV Community

Cover image for Code Smell 225 - Pass by Reference
Maxi Contieri
Maxi Contieri

Posted on • Originally published at maximilianocontieri.com

2

Code Smell 225 - Pass by Reference

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.

  2. Declare variables as constants

  3. Refactor the code

  4. Make objects immutable 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

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;
         }
     }
}
Enter fullscreen mode Exit fullscreen mode

Right

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;
         }
     }
}
Enter fullscreen mode Exit fullscreen mode

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

More Info

Modifiyng Method Parameter

Wikipedia

Disclaimer

Code Smells are my opinion.

Credits

Photo by Quino Al on Unsplash


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

Wes Dyer


This article is part of the CodeSmell Series.

Warp.dev image

Warp is the highest-rated coding agent—proven by benchmarks.

Warp outperforms every other coding agent on the market, and gives you full control over which model you use. Get started now for free, or upgrade and unlock 2.5x AI credits on Warp's paid plans.

Download Warp

Top comments (2)

Collapse
 
jankapunkt profile image
Jan Küster 🔥

Still a big issue in plain JavaScript, even with Object.freeze, if not applied correctly. Fortunately, many good libraries do exist for immutability and functional programming in Js!

Collapse
 
mcsee profile image
Maxi Contieri

Gen AI apps are built with MongoDB Atlas

Gen AI apps are built with MongoDB Atlas

MongoDB Atlas is the developer-friendly database for building, scaling, and running gen AI & LLM apps—no separate vector DB needed. Enjoy native vector search, 115+ regions, and flexible document modeling. Build AI faster, all in one place.

Start Free

👋 Kindness is contagious

Discover fresh viewpoints in this insightful post, supported by our vibrant DEV Community. Every developer’s experience matters—add your thoughts and help us grow together.

A simple “thank you” can uplift the author and spark new discussions—leave yours below!

On DEV, knowledge-sharing connects us and drives innovation. Found this useful? A quick note of appreciation makes a real impact.

Okay