3

I always thought pass by value is a legacy from the early languages, because the designers had never seen anything else. But after seeing the brand new languages like Go adapting the same principle confused me.

The only advantage I can think of is you make sure that the value you are passing won't be modified. But every time you need to pass a big structure to a function, you need to pass the pointer (or reference) to prevent copying, if the language permits it.

To prevent modification of parameters, some constness mechanism could be introduced instead of making the whole language pass by value.

I have been coding for years and I rarely needed to pass by value. Almost always, I don't need my value/object to be copied to a function call; and often I don't need it to be modified inside the function*.

What is the motivation behind making modern languages pass by value? Are there any advantages that I am not aware of?

Edit: When I say pass by value, I don't mean primitives. They are easy and cheap to pass by value. My main focus is objects or structs that consists of more than 1 primitive and thus expensive to copy.

*: I have asked around and others reported similar thing with their parameter usage.

6
  • 1
    Passing by reference for a complex, multiple layered object can lead to pointer confusion. Some languages (.NET definitely, Java maybe) do not perform deep copies of objects. The result is hard to find bugs when you think you are working with a new instance of a child object when it is really a shared child object of every object that was copied/cloned. I too rarely pass by value. Commented Feb 22, 2014 at 20:38
  • 2
    @AdamZuckerman: if you are passing by ref when you don't need to (and I am includinging performance reasons when dealing with large structures as "need to") you are doing the next programmer to work on your code a disservice, and that is assuming you understand what you are doing. It is non-standard behaviour which can introduce subtle and hard to track down bugs. It makes all of your variables globals.
    – jmoreno
    Commented Feb 22, 2014 at 22:05
  • I didn't say that I don't do it. In places where I want to modify the passed in variable without affecting the caller, of course I would pass by value. My comment was about some languages not eating their own dog food. Commented Feb 22, 2014 at 22:37
  • @AdamZuckerman: does "passed in variable" mean passed in object, the variable in the calling function or the local parameter? Not knowing the difference between these is a common misunderstanding that leads to people using by ref when they shouldn't. By Ref is used to change the variable in the calling function, something that is a fairly uncommon necessity even in languages without support for returning multiple values.
    – jmoreno
    Commented Feb 23, 2014 at 2:02
  • If you declare a variable of any type in a routine, then use that variable as an argument to another routine, passing that variable by value prevents the called routine from modifying the variable in the calling routine. Passing it by ref allows the called routine to modify the value of the variable in the calling routine. I hope this is a clearer statement of what I tried to say before. Some languages do not have the concept of multiple return values. Some languages do not have the concept of any return values. In the latter case, everything would be passed by ref or global in scope. Commented Feb 23, 2014 at 3:59

3 Answers 3

14

Pass-by-reference makes some things more efficient and allows updates to parameters within subroutines, but it is by no means a panacea.

Imagine a parallelized application. When using pass-by-reference, then you need a locking mechanism to keep a sane state. Pass-by-value doesn't have this limitation. I've seen multi-threaded programs which spend more time waiting for mutexes than processing data. Here pass-by-value can be a big efficiency gain.

Imagine a distributed application. This is always pass-by-value, because the remote system needs its own copy of the object. Pass-by-reference must be simulated using proxy objects. It requires extra network overhead to keep the proxy objects in sync. Here pass-by-value save not only processing time, but reduces network bandwidth.

7

Pass by value is just a corollary to value semantics (i.e. by-value variables, object members, etc). Aside from the advantage you mention, this adds:

  • Very efficient aggregates. A type like struct Foo { T a; U b; } does not require a separate allocation or extra indirection for the members.
  • Zero cost abstractions: class IntWithDifferentBehavior { int value; ... } is exactly as efficient as an int, assuming static dispatch for the methods.
  • It goes very well with tracking ownership and lifetimes. One consequence is support for deterministic destruction, enabling RAII as an alternative to (semi-)manual resource management.

In addition, pass-by-value is much easier to make memory safe and efficient. If you pass pointers/references to stack-allocated memory, you need to make sure the memory outlives the reference. If you instead use automatic memory management to ensure that, you pay a run-time price for that.

10
  • I take it your code samples are in C++, right? Because they would be also valid in C#, and there class is not a zero-cost abstraction.
    – svick
    Commented Feb 22, 2014 at 22:10
  • 2
    @svick They're not in any language in particular. And no, in C# it is not a zero cost abstraction, because classes in C# don't have value semantics. That is exactly what my answer is saying.
    – user7043
    Commented Feb 23, 2014 at 8:44
  • 1
    Passing values by reference is much easier to make memory-safe and efficient than passing references by value. Passing pointers is unsafe, but in frameworks like .NET which support pass-by-reference semantics, any "byref" passed to a method is guaranteed to be destroyed when it goes out of scope.
    – supercat
    Commented Feb 25, 2014 at 0:33
  • @supercat How does it guarantee that? I'm pretty certain it requires further work that isn't necessary when passing the same thing without ref. Perhaps language-level restrictions on what can be done with ref parameters? Those need to be defined and checked, mind you.
    – user7043
    Commented Feb 25, 2014 at 11:37
  • @delnan: In .NET, the code verifier will not allow a byref to be copied to any kind of storage location of non-automatic duration, nor used as a return value of any user-defined function [array indexing returns a byref, but that's a special case]. While it would be possible to define slightly more permissive rules and still uphold the required guarantees, the rule as it exists achieves 99% of the benefits of byrefs without overly complicating verification.
    – supercat
    Commented Feb 25, 2014 at 13:45
2

I always thought pass by value is a legacy from the early languages, because the designers had never seen anything else.

This is a bogus characterization in two respects:

  1. It (kind of) assumes that pass-by-value was the original form of passing, and that it was superseded by better things. In fact, the history clearly demonstrates this is not true (as does the Answer you cited as a source).

  2. It implies (without any logical argument or supporting evidence) that the designers of mainstream programming languages are ignorant of programming language history. A proper review of the relevant documentation will reveal that this notion is completely false ... not to mention insulting to the people involved.


The actual decision to support pass-by-reference, pass-by-value and/or one of the more obscure / historic forms (such as pass-by-copying or pass-by-name) is heavily intertwined with other aspects of the overall language design ... and motivated by the goals of the design.

For example:

  • Is the goal to provide a language where programs are easy to read and understand?

  • Is the goal to provide a language which maximizes "expressive power" or "conciseness"?

  • Is the goal to provide a language which maximizes "performance" on certain kinds of problems?

  • Is the goal to support a particular programming "paradigm" over others; e.g. procedural, OO, functional, pure functional, parallel / concurrent?

And so on.

In short, they have gone way beyond simplistic thinking like "the advantages of pass by value".


I have been coding for years and I rarely needed to pass by value. Almost always, I don't need my value/object to be copied to a function call.

Something does not make sense with that ...

If you have been coding for years in Java, C, C++, C# or most other modern programming languages, you have been using pass by value most of the time. It is the default way of doing things ... and in some languages (like Java) it is the only way.

For example

    int i = 1;
    myFunction(i);

AFAIK, i will be passed by value in C, C++, Java and C#. If you want pass by reference (in C and C++) you have to write it explicitly; e.g.

    myOtherFunction(&i);

Do you actually do that all the time in your code? For primitive-typed variables? I don't think so.

4
  • Of course I am aware that language designers are not ignorant and it is very hard to design languages. I am sorry if I offended someone. Actually, first I wrote something like 'When I say value I don't mean primitives of course.' but I thought it is obvious, I decided to omit it for clarity in my original post. But now I will update my question accordingly.
    – nimcap
    Commented Feb 23, 2014 at 2:55
  • @nimcap: C# and Java use pass by value for complex objects, not just for primitives. Mind you, they pass a reference by value, but this is not at all the same thing as passing a value by reference. C# also supports structs (in which case the behavior is similar to pass by value in C++) and pass by reference (in which case the behavior is similar to pass by reference in C++).
    – Brian
    Commented Feb 23, 2014 at 16:18
  • Actually I might be misusing the terms. I used the term pass-by-value when the actual object passed to a function is copied, not the reference.
    – nimcap
    Commented Feb 23, 2014 at 17:28
  • 3
    @nimcap - Yes. If that is what you meant, then you are misusing the term. Pass-by-value is actually talking about any kind of value.
    – Stephen C
    Commented Feb 24, 2014 at 8:15

Not the answer you're looking for? Browse other questions tagged or ask your own question.