11

I am confused about the meaning of "pass by reference" in C and C++.

In C, there are no references. So I guess pass by reference means passing a pointer. But then why not call it pass by pointer?

In C++, we have both pointers and references (and stuff like iterators that lies close). So what does pass by reference mean here?

Registered User
  • 2,239
  • 3
  • 32
  • 58
  • In C, there are references, and AFAIK they behave the same way as in C++ – galinette May 10 '16 at 11:02
  • 7
    See http://stackoverflow.com/questions/57483/what-are-the-differences-between-a-pointer-variable-and-a-reference-variable-in and http://stackoverflow.com/questions/2229498/passing-by-reference-in-c – Schore May 10 '16 at 11:03
  • "Pass by reference" is a fixed term and in C it should not be used. "Passing **a** reference" can be used, though, because that can imply the address is taken first. And iterators are **not** close to these basic types. – too honest for this site May 10 '16 at 11:03
  • 1
    In general reference is an access to the variable that allows to change the value which it refers... In C you can do dereference of a pointer so the term reference is also valid... – W.F. May 10 '16 at 11:04
  • @Schore: Flag as duplicate. – too honest for this site May 10 '16 at 11:04
  • 1
    @Olaf Ah I thought I was out of flags already today :) – Schore May 10 '16 at 11:05
  • I was told it just means that you are not using a duplicate variable but the reference to it. It is quite good because it does not need the program to copy the variable. For example, copying a class could take a long time or tones of memory. If you simply pass the reference you'll work on the class instead of working on a copy of the class – Hearner May 10 '16 at 11:08
  • 5
    The unpopular answer: it is all nonsense invented by confused so-called computer scientists. There is nothing called "references" or "pointers" inside a computer or in your actual machine code. There are just values and addresses. You can call an address whatever you like, it won't change the fact that it is just a raw number. When you pass something to a function, your computer gives the option to pass a copy of the value through a data register or on the stack, or the option to pass the address of the data through an index register. No other kind of computers exist in the real world. – Lundin May 10 '16 at 11:51
  • 1
    @Lundin you are confusing all those bash/js/etc programmers who know that, really, computers run text lines directly. – Martin James May 10 '16 at 13:45
  • 1
    'reference' means different things, depending on where you are standing and what you are doing - it's grossly overloaded. For instance, if you are trying to reverse-engineer/debug someone else's C++ code, a variable passed by reference is an annoying and stupid obfuscation that was specifically designed to prevent maintenance and enhancement developers from knowing whether changing a var value is propagated to the caller, or not, without looking up its declaration. In C, it would have to have a star in front of it, so you know immediate. – Martin James May 10 '16 at 13:51
  • 1
    @Lundin THANK YOU, no one will admit this on here, this is the only correct answer. – ICW Sep 18 '19 at 18:33
  • 1
    @MartinJames Lundin is the only one here fighting the confusion... – ICW Sep 18 '19 at 19:11

10 Answers10

20

In colloquial usage, "pass by reference" means that, if the callee modifies its arguments, it affects the caller, because the argument as seen by the callee refers to the value as seen by the caller.

The phrase is used independent of the actual programming language, and how it calls things (pointers, references, whatever).

In C++, call-by-reference can be done with references or pointers. In C, call-by-reference can only be achieved by passing a pointer.

"Call by value":

void foo( int x )
{
    // x is a *copy* of whatever argument foo() was called with
    x = 42;
}

int main()
{
    int a = 0;
    foo( a );
    // at this point, a == 0
}

"Call by reference", C style:

void foo( int * x )
{
    // x is still a *copy* of foo()'s argument, but that copy *refers* to
    // the value as seen by the caller
    *x = 42;
}

int main()
{
    int a = 0;
    foo( &a );
    // at this point, a == 42
}

So, strictly speaking, there is no pass-by-reference in C. You either pass the variable by-value, or you pass a pointer to that variable by-value.

DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • 1
    good point that in fact any parameter is passed by value, just with c++ references it is not so obvious – 463035818_is_not_an_ai May 10 '16 at 16:23
  • @tobi303: Actually, a C++ reference *is* passing by reference. That is why a C++ reference cannot be the last named parameter in a variadic function: When you use `va_start` (which is *intended* to take the address of the last named parameter on the stack, so you can access the next parameter from there), what happens with a C++ reference is that you are pointing to the variable in the **caller's** stack frame. Needless to say, that won't work as intended. (As I found out after some debugging "fun".) Pointers work as expected (the pointer is passed by value). – DevSolar Mar 29 '17 at 08:46
  • thanks for the clarification, though I will need some time to really understand what you are saying... – 463035818_is_not_an_ai Mar 29 '17 at 08:51
  • @tobi303: Consider `called_p( int * ptr, ... ) { /* ... */ }` and `int x = 42; called_p( &x, "foo" );`. Now, `ptr` will hold the address, and allow me to modify, `x`. But if I take the address of `ptr`, inside `called_p()`, it will be an address on the stackframe of `called_p()`. I can use that to get access to `"foo"`. -- Now, consider `called_r( int & ref, ... ) { /* ... */ }` and `int x = 42; called_r( x, "bar" );`. Now, `ref` **is** `x`. If I take the address of `ref`, it will be the address of `x` *in the stackframe of the caller*. I cannot use it to get access to `"bar"`. – DevSolar Mar 29 '17 at 09:35
  • However, array passing works *as if by reference*, even though it's technically pass-by-value: `void foo(int bar[]);` can be called with `int baz[42]; foo(baz);`, and the caller will see the changed array contents. Technically, the function argument *decays* into a pointer, both in the function signature and the call, so it's technically passing a pointer by value, but the visible effect is that of passing an array by reference. – cmaster - reinstate monica Sep 21 '17 at 10:28
  • @cmaster: Well, but you can't pass an array in C, can you? *Because* it decays into a pointer. That's why you can't `sizeof` an array in the called function... because it's a pointer, passed by value. ;-) – DevSolar Sep 21 '17 at 11:04
  • Even in C++, is it not just pass by value? Is there a real concept of pass by reference? What I mean is: when we call the func(int &a) {}, we call this function as func(k). Here k is declared as integer in calling portion. So is it not something like func(int &a=k)? That means we assign k to int &a. – Rajesh Mar 12 '20 at 15:51
  • @Rajesh: Pointers are data objects of their own (you can take the address of a pointer, which is distinct from the address of the object pointed to). References are merely an alias, a different name, a *reference* to the actual data object. You can call it `a` or `k`, but it is *the same object*. – DevSolar May 04 '20 at 13:00
5

In C, there are no references

There are no reference variables. But you can refer to objects using pointers. Therefore pointers are "references" from an abstract point of view.

But then why not call it pass by pointer?

You can call it pass by pointer. Reference is a more general term than pointer. It is often preferable to use the more general term when you want to discuss abstractions and want to ignore implementation details. You would call it pass by reference for the same reason that you call a variable "integer" rather than "int32_t".

In C++, we have both pointers and references (and stuff like iterators that lies close). So what does pass by reference mean here?

Depends on context. Often it means that the function argument is a reference variable, but it may also refer to a pointer, iterator, a reference wrapper... anything that referes to an object.


Reference is an abstract concept that exists beyond c and c++; even beyond programming. In c++, the term is ambiguous with reference variables and the context and convention (which isn't universal) determines the meaning.

eerorika
  • 232,697
  • 12
  • 197
  • 326
3

In C, there are no any reference variables, but you can pass by reference with using pointers.

In wikipedia, there is this definition. In call-by-reference evaluation (also referred to as pass-by-reference), a function receives an implicit reference to a variable used as argument, rather than a copy of its value. So this term is for type of parameter passing as mentioned by Thomas. So yes, since C is older than C++, also this idea is older than C++.

However, in C++ both pointers and references can be used for passing to the function(Call by address and call by reference). Actually they are working the same way, they have only a few differences.

  • Once a reference is created, it cannot be later made to reference another object; it cannot be reseated. This is often done with pointers.
  • References cannot be NULL. Pointers are often made NULL to indicate that they are not pointing to any valid thing.
  • A reference must be initialized when declared. There is no such restriction with pointers

With these differences, if you use call by reference instead of call by pointer, you can reduce the possibility of NULL pointer error kind of problems.

Prometheus
  • 1,522
  • 3
  • 23
  • 41
3

Let's clear your confusion.

In C, there are no references. So I guess pass by reference means passing a pointer. But then why not call it pass by pointer?

Because every argument passing in C is pass-by-value. Even a pointer argument is a copy. But it contains (or points to, if you prefer) the same value -- memory address. That is how you can change the variable it points to, but not the pointer itself. Since it's a copy, whatever you do will not affect the pointer on the caller level.

In C++, we have both pointers and references (and stuff like iterators that lies close). So what does pass by reference mean here?

It means, that the argument is an alias of a variable on the caller level, not a copy, which allows us to change it.

Hope that helped.

HighPredator
  • 790
  • 4
  • 21
1

"Pass by reference" (or "call by reference") is a term for a type of parameter passing when calling a function, and the idea is older than C++. It does not necessarily have to be done using C++ "references". C doesn't have a built-in mechanism to do this, so you have to use pointers.

Thomas Padron-McCarthy
  • 27,232
  • 8
  • 51
  • 75
1

A reference in general is an instance that is referencing something else. Thus in a wider sense, also a pointer can be considered as one possible implementation of a reference. References in C++ are just called references, because apart from referencing something they offer no other features.

Pass-by-reference is used in general to distinguish from pass-by-value. Whether it is via pointer or via a reference is often just a minor detail. However, with C++ references it is imho more clear what is the purpose of the function parameter. Eg:

int foo(int& a);         // pass-by-reference
int foo(const int& a);   // is pratically pass-by-value 
                         // (+ avoiding the copy of the parameter)

on the other hand, with references (as compared to pointers) it is not so obvious at the call site if it is pass-by-value or pass-by-reference. E.g.

int x;
int y = foo(x);  // could be pass-by-value or pass-by-reference
int z = foo(&x); // obviously pass-by-reference (as a pointer)
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
1

Imagine you have to paint your house...

by value: you bring a copy of your house to the painter => much effort (maybe on rails)
by reference: you give your house address to the painter so he can come and paint it

V. Sambor
  • 12,361
  • 6
  • 46
  • 65
  • 2
    Not quite correct. If you have your house painted *by value*, the painter would get a *copy* of your house to paint, while you would keep your (unpainted) original. – DevSolar May 10 '16 at 11:26
  • you are right about this, I wanted to emphasize the effort for value passing and the advantage of reference... – V. Sambor May 10 '16 at 11:28
  • @DevSolar and then once the copy of the house is painted, the painter would blow it up. – Jabberwocky May 10 '16 at 12:04
  • 2
    @MichaelWalz: Well, actually, he would just leave it there until some other structure were erected in its place. You could still visit it, but it'd be your own fault if you'd be pancaked by the new structure as there would be no advance warning. ;-) – DevSolar May 10 '16 at 12:20
  • @MichaelWalz the painter should be some kind of terrorist – V. Sambor May 10 '16 at 12:23
0

Just to add to the answers, referencing does not mean reference by address. The compiler may use any method to reference to a variable.

-1

when you pass something by reference you're working with the address and not the value of a variable directly, If you use a reference parameter you're getting the address of the variable you pass in.

From there you can manipulate it how ever you want as the variable you passed in WILL change if you change the reference in the function. It's an easier way to work with large amounts of a data it really just saves on memory etc..

suroh
  • 917
  • 1
  • 10
  • 26
-2

In C there are two concepts

1. Call by value - Here copy of values are passed so actual values will not change outside the function.

2. Call by reference - but here actual values (Address of actual operands) are passed so it will change the values globally.

Where in C++ there are two concepts

1. Pass by value - it is same as c, actual values will not change, scope of this values are of function only.

2. Pass by Reference - actual values (Address of actual operands) are passed so it will change the values globally, it means if values gets changed then it will affect in whole program.

In Pass by Reference, the address of operands are passed that's why it is called as Pass By Reference not as pointer.

Jay Patel
  • 2,341
  • 2
  • 22
  • 43