If C does not support passing a variable by reference, why does this work?
#include <stdio.h>
void f(int *j) {
(*j)++;
}
int main() {
int i = 20;
int *p = &i;
f(p);
printf("i = %d\n", i);
return 0;
}
Output
$ gcc -std=c99 test.c $ a.exe i = 21
Because there is no pass-by-reference in the above code. Using pointers (such as
void func(int* p)
) is pass-by-address. This is pass-by-reference in C++ (won't work in C):Your example works because you are passing the address of your variable to a function that manipulates its value with the dereference operator.
While C does not support reference data types, you can still simulate passing-by-reference by explicitly passing pointer values, as in your example.
The C++ reference data type is less powerful but considered safer than the pointer type inherited from C. This would be your example, adapted to use C++ references:
That is not pass-by-reference, that is pass-by-value as others stated.
The rule is the following:
Let's try to see the differences between scalar and pointer parameters of a function.
Scalar variables
This short program shows pass-by-value using a scalar variable.
param
is called the formal parameter andvariable
at function invocation is called actual parameter. Note incrementingparam
in the function does not changevariable
.The result is
Illusion of pass-by-reference
We change the piece of code slightly.
param
is a pointer now.The result is
That makes you believe that the parameter was passed by reference. It was not. It was passed by value, the param value being an address. The int type value was incremented, and that is the side effect that make us think that it was a pass-by-reference function call.
Pointers - passed-by-value
How can we show/prove that fact? Well, maybe we can try the first example of Scalar variables, but instead of scalar we use addresses (pointers). Let's see if that can help.
The result will be that the two addresses are equal (don't worry about the exact value).
Example result:
In my opinion this proves clearly that pointers are passed-by-value. Otherwise
ptr
would beNULL
after function invocation.No pass-by-reference in C, but p "refers" to i, and you pass p by value.
pointers and references are two different thigngs.
A couple of things I have not seen mentioned.
A pointer is the address of something. A pointer can be stored and copied like any other variable. It thus have a size.
A reference should be seen as an ALIAS of something. It does not have a size and cannot be stored. It MUST reference something, ie. it cannot be null or changed. Well, sometimes the compiler needs to store the reference as a pointer, but that is an implementation detail.
With references you don't have the issues with pointers, like ownership handling, null checking, de-referencing on use.
Because you're passing the value of the pointer to the method and then dereferencing it to get the integer that is pointed to.