85

A simple question for which I couldn't find the answer here.

What I understand is that while passing an argument to a function during call, e.g.

void myFunction(type myVariable)
{
}

void main()
{
    myFunction(myVariable);
}

For simple datatypes like int, float, etc. the function is called by value.

But if myVariable is an array, only the starting address is passed (even though our function is a call by value function).

If myVariable is an object, also only the address of the object is passed rather than creating a copy and passing it.

So back to the question. Does C++ pass a object by reference or value?

user3041058
  • 1,520
  • 2
  • 12
  • 16
  • 2
    In the case of an array, you are passing the pointer to the first element *by value*. It's not passing by reference in C++ unless the argument is a reference type (it has an `&` in it). – Joseph Mansfield Jan 19 '14 at 10:19
  • 10
    @juanchopanza A list of books ?? :0 Seriously, downvotes?? I have to buy all those books to know answer to the question. I sorry but am saddened – user3041058 Jan 19 '14 at 10:29
  • 6
    This isn't a bad question in general. But it does demonstrate that maybe you should sit down a bit with the fundamentals of the language, and experiment through a few test cases. If you did, you would quickly see that the default behavior of passing objects is to copy. You could see this by passing a `std::vector myVariable` parameter, adding to it in `myFunction` and printing out there, and then printing it in `main`. The modifications will not be reflected in `main`'s output. But C++ can be bent beyond these conventions; that's part of its madness and charm. Read up, don't despair! – HostileFork says dont trust SE Jan 19 '14 at 10:33
  • 5
    My book didnt clarify how objects were passed, along with array passing. I was confused. I google searched and searched here. All questions were specefic. Not finding a general answer, I decided to ask – user3041058 Jan 19 '14 at 10:34
  • duplicate? lol. somebody please fix this. – Karoly Horvath Jan 19 '14 at 10:47
  • 12
    [Could we please be a bit nicer to new users?](https://meta.stackexchange.com/questions/9953/could-we-please-be-a-bit-nicer-to-new-users). They hunt in packs around here. But don't worry about them. – jww Jan 25 '14 at 03:13
  • 3
    Good question! :) I was looking for this – jjepsuomi Jun 08 '16 at 21:59
  • 4
    I think this is a perfectly valid and helpful question. I have several books on C++ and have been using it off and on for going on 5 years now (for school assignments mostly) but I can't always remember how all the different languages I am exposed to operate at their lowest level. At work I use C# and a bit of Python, C++ for random projects at home, and this last week I started getting serious about C. They all do this a bit differently and I needed a quick and easy way to refresh on this subject in C++ without digging out some 400-600+ page books. – RTHarston Feb 09 '19 at 19:01
  • @JosephMansfield are you sure that pass by reference means passing with & in syntax. Are not you relating pass by reference to syntatical thing instead of conceptual thing. In my view pass by reference is passing the ADDRESS whether by & or without it (as it happens in arrays). – a Learner Jun 18 '20 at 11:33

5 Answers5

76

Arguments are passed by value, unless the function signature specifies otherwise:

  • in void foo(type arg), arg is passed by value regardless of whether type is a simple type, a pointer type or a class type,
  • in void foo(type& arg), arg is passed by reference.

In case of arrays, the value that is passed is a pointer to the first element of the array. If you know the size of the array at compile time, you can pass an array by reference as well: void foo(type (&arg)[10]).

Oswald
  • 31,254
  • 3
  • 43
  • 68
  • 3
    I think we should take terms carefully when talking about this. Pass by value means *"What you get is the value of the parameter"*, and pass by reference means *"What you get is a reference/alias of the parameter"*, independently of what the compiler really does (Copying, moving, eliding copies, passing pointers, passing references, etc). I have posted this comment because I think identifying *pass by value* with *copy* and *pass by reference* with *no copy* is a common source of missunderstandings, starting with C (Which has no pass by reference, emulates it with pointers), C++, and Java. – Manu343726 Jan 19 '14 at 18:09
  • @Manu343726 C has no pass by reference. How? If pass by reference means passing the address then how C has not pass by reference? I think pass by reference is not related to REFERENCE VARIABLES but it is related to passing the address whether by pointers or reference variables. – a Learner Jun 18 '20 at 11:25
  • 1
    @aLearner Pass by reference means creating an alias to already existing object. So when you use "int & a = x" you are creating new name for x. Main reason for doing so is to change the value of x when a is modified. In C there is no way to add new names to same existing objects so we take an address of a object and pass it so that we can change value of original variable. With pointer you are actually using copy by value. You are copying the value of address when you use "int * a = &x". And thats what Manu343726 mean by emulating reference by using pointers. – Mandar Sadye Jul 24 '21 at 03:48
28

C++ always gives you the choice: All types T (except arrays, see below) can be passed by value by making the parameter type T, and passed by reference by making the parameter type T &, reference-to-T.

When the parameter type is not explicitly annotated to be a reference (type &myVariable), it is always passed by value regardless of the specific type. For user-defined types too (that's what the copy constructor is for). Also for pointers, even though copying a pointer does not copy what's pointed at.

Arrays are a bit more complicated. Arrays cannot be passed by value, parameter types like int arr[] are really just different syntax for int *arr. It's not the act of passing to a function which produces a pointer from an array, virtually every possible operation (excluding only a few ones like sizeof) does that. One can pass a reference-to-an-array, but this explicitly annotated as reference: int (&myArray)[100] (note the ampersand).

  • 2
    +1 for pointing out that `int arr[]` is really just `int *arr`. That makes it clear why passing an array by value seems to work differently than other types T, because in reality is doing exactly what you would expect if you were to write `int *arr` instead. – RTHarston Feb 09 '19 at 18:49
  • @RTHarston `arr[]` is not `*arr`. `int arr[]` declares and makes space for an array, `arr` *is* the address of the first element, not a pointer. `int *arr2` declares and makes space for a *pointer* to an int (or the first element of an array). A pointer might receive the address of an array, `arr2 = arr`, but the opposite is not possible `arr = ...`. An argument `arr` is a mere address, while in the case of `arr2` the content of the pointer is passed. – Déjà vu Oct 02 '22 at 09:53
  • @Déjàvu thanks sharing. I do know that `arr[]` and `*arr` aren't the same thing, and I knew that three years ago too, so I'm not sure what I meant exactly in my previous comment. `arr[]` can be automatically coerced into `*arr`, but that doesn't make it the same thing. I wonder if I was thinking at the assembly level? The type system knows `arr[]` and `*arr` are different, but in assembly they could easily look the same when the method is called, since just a pointer to the base of the array is passed. – RTHarston Nov 01 '22 at 14:05
9

C++ makes both pass by value and pass by reference paradigms possible.

You can find two example usages below.

http://www.learncpp.com/cpp-tutorial/72-passing-arguments-by-value/

http://www.learncpp.com/cpp-tutorial/73-passing-arguments-by-reference/

Arrays are special constructs, when you pass an array as parameter, a pointer to the address of the first element is passed as value with the type of element in the array.

When you pass a pointer as parameter, you actually implement the pass by reference paradigm yourself, as in C. Because when you modify the data in the specified address, you exactly modify the object in the caller function.

mcvkr
  • 3,209
  • 6
  • 38
  • 63
0

In C++, types declared as a class, struct, or union are considered "of class type". These are passed by value or you can say a copy using copy constructor is passed to the functions. This is pretty evident when we implement binary trees wherein you almost always have a Node * type of param in the recursive function acting on the binary tree. This is so as to facilitate modification of that node. If the node were to be passed as is (i.e not being a pointer type), the modifications to the nodes would have been to the local copy. Even in the case of vectors, while passing a copy of vectors is passed to the functions, to avoid which we use a reference &.

-6

C++ passes arguments that are no pointers (int*) or references (int&) by value. You cannot modify the var of the calling block in the called function. Arrays are pointers.

scraatz
  • 419
  • 2
  • 7
  • 3
    C++ also passes pointer by value. There is no magical exception. – juanchopanza Jan 19 '14 at 10:18
  • 1
    In C++ terminology, the fact that a parameter type is a pointer doesn't influence whether its by value or by reference. If it's just a pointer, it's by value. If it's a reference to a pointer, it's by reference. – Joseph Mansfield Jan 19 '14 at 10:18
  • 1
    What I meant was, the argument is declared as a pointer or a reference. Sorry for my bad english. I understood the question in a sense of "Can I modify the passed var within the called function. – scraatz Jan 19 '14 at 10:20
  • 5
    If the argument is declared as a pointer, the pointer is passed by value. If it is declared as reference to pointer, it is passed by reference. Also, arrays aren't pointers. – juanchopanza Jan 19 '14 at 10:22
  • juanchopanza - arrays degenerate to pointers. See, for example, https://stackoverflow.com/questions/4223617/standard-conversions-array-to-pointer-conversion. – jww Jan 25 '14 at 03:17
  • @noloader: A value of array type is implicitly converted to a value of pointer type in some, but not all, contexts. – newacct Jan 27 '14 at 06:53
  • @juanchopanza `C++ also passes pointer by value.` But thats the pass by reference in itself. – a Learner Jun 15 '20 at 18:11
  • @aLearner Sorry, I don't understand the second sentence in your comment. – juanchopanza Jun 15 '20 at 19:21
  • @juanchopanza I mean to say that in pass by reference also we pass the pointer by value if we are passing the address of a variable. In fact we always pass pointer by value. – a Learner Jun 18 '20 at 11:16
  • @aLearner I think you're using C terminology. In C++, pointers are not references. When we "pass by reference" we pass a reference, not a pointer. – juanchopanza Jun 18 '20 at 12:57