Skip to content
Theory · Functions · lesson 2 of 13

Parameters: by value and by reference

Picture handing a colleague a document to edit. You can hand over a photocopy: the colleague scribbles all over it, and your original stays clean. Or you can hand over the original itself, and then every edit ends up on your copy. A C++ function also gets its argument in one of these two ways, and the call does not show which.

The inc_copy function increases its parameter by one, but the variable passed to it stays the same:

C++
#include <iostream>

void inc_copy(int x) {
    ++x;
    std::cout << x << '\n';  // 2
}

int main() {
    int n = 1;
    inc_copy(n);
    std::cout << n << '\n';  // 1
}

Inside the function, x is already 2, while n in main is still 1.

A copy of the argument

Let's walk through the call inc_copy(n) step by step:

  1. A new variable x is created, and the value of the argument n, that is 1, is copied into it.
  2. ++x increases the copy to 2, and the function prints 2.
  3. The function ends, and x disappears together with every change made to it.
  4. main prints n, and n is still 1.

This is pass by value: the function works with a photocopy, not with n itself. The analogy limps in one place: you cannot take the copy home, since it lives only until the function ends.

A changed copy can be returned with return: the caller gets the new value, and the original variable stays as it was.

Reference parameters

To let a function change the caller's variable, the parameter is declared as a reference: an & goes after the type. A reference is another name for an existing variable, not a copy of it. It works like a nickname: "Sasha" and "Alexander" are one and the same person.

C++
#include <iostream>

void inc_ref(int& x) {
    ++x;
}

int main() {
    int n = 1;
    inc_ref(n);
    std::cout << n << '\n';  // 2
}

Inside inc_ref, the name x denotes n itself, so ++x increases n. The call creates no new variable: for the duration of the call, one variable has two names.

Step through both calls and watch n in the main frame: after inc_copy it is unchanged, after inc_ref it is not.

LiveA copy and a reference, step by stepstep 1 of 8 · frames: 1

main gets n with the value 1

Watch n in the main frame

The call looks the same as inc_copy(n): only the function's declaration tells you that the argument will change. So when you read someone else's code, look for the & in the parameter list.

"How does pass by value differ from pass by reference?" is a question interviewers like to ask. The short answer: by value the function gets a copy, by reference it gets the variable itself.

Common mistake

A number is passed to a function that takes a reference:

C++
void inc_ref(int& x) {
    ++x;
}

int main() {
    inc_ref(5);  // ✗
}
TEXT
error: no matching function for call to 'inc_ref'

This is a compiler error. A reference must become another name for some variable, and the number 5 has no variable of its own: there is nothing to increase. Pass a variable instead, for example inc_ref(n).

Key points

  • By value, the function gets a copy of the argument; its changes vanish with the copy.
  • A reference parameter int& x is another name for the caller's variable; changes are visible outside.
  • The calls inc_copy(n) and inc_ref(n) look the same: only the & in the declaration shows the difference.
  • Only a variable can be passed to an int& parameter, not a number such as 5.

Subscribe to take the course

The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.

Sign in another way