A* ap= new A(); //object on heap func(ap); // NOT CALL BY REFERENCE, scream the language lawyers!

You are the one who seems to be screaming, not the supposed "language lawyers" func is defined as func(A*); It's the actual C++ spec that calls this call-by-value

A a; // object on stack func(&a); // NOT CALL BY REF, scream the lawyers again!

Again, you are screaming here. You're using the address-of operator to obtain a pointer. This pointer is then passed to a function for which we already established it was call-by-value. This example adds little to nothing. It's the actual C++ spec that calls this call-by-value.





func2(a); // FINALLY, A CALL BY REFERENCE, scream the lawyers, with their whiny voices!

And again, you are the one who's screaming. func2 is defined as func2(A &); So yes, according to the C++ standard this is called call-by-reference.

The java-is-call-by-value language lawyers would have us state that the non-stack-residing object "*ap" is NOT passed by reference to func solely because "ap" is passed by value.

Indeed, since you'e not passing the dereferenced version of "ap" to func(). The call you're doing is func(ap), so what's getting passed is the pointer "ap", and that pointer is passed by value.

Same with the second invocation of func using &a.

Because it is the same. In this case too you are not passing an object. What you are passing is the address of an object, which is a pointer. Since it's the exact same func, the semantics are the same here. The semantics are tied to the definition of the function, not to where a call-site happens to obtain a pointer from.

How this helps the language lawyers sleep at night is beyond me!

Mark, we very much know all of this is beyond you. It's very obvious.

Do notice that there were only two examples being shown. From the list given by Arjan:

Value variable passed by-reference (func2) Pointer variable passed by-value (func)

No definition of func was given, but assume the following:

void func(A* aPointer) {

aPointer = new A();

}

This assignment will have zero effect on the variable "ap" that's being passed in. If you were to use call-by-reference however this would have an effect.

This is easily demonstrated with the following code:

#include <iostream>

class A {

public:

int value;

};

void callByValuePtrAssign(A* a) {

a = new A;

a->value = 0;

}

void callByReferencePtrAssign(A* &a) {

a = new A;

a->value = 0;

}

int main() {

A* a = new A;

a->value = 3;

cout << "Initial value:" << a->value << endl;

callByValuePtrAssign(a);

cout << "After call by value:" << a->value << endl;

callByReferencePtrAssign(a);

cout << "After call by reference:" << a->value << endl;

return 0;

}

without touching the original

#include <iostream>

class A {

public: int value;

};

void callByValueMutate(A* a) { a->value = 1;

}

void callByReferencePtrAssign(A* &a) {

a = new A; a->value = 0;

}

int main() {

A* a = new A; A* b = a; a->value = 3;

cout << "Initial value A:" << a->value << endl; cout << "Initial value B:" << b->value << endl;

callByValueMutate(a);

cout << "After call by value A:" << a->value << endl; cout << "After call by value B:" << b->value << endl;

callByReferencePtrAssign(a);

cout << "After call by reference A:" << a->value << endl; cout << "After call by reference B:" << b->value << endl;

return 0;}

callByValueMutate function, we mutate the object.

As expected, after the call we see the change in main via both a en b. This is logical, they point to the same instance. A pointer was involved, the state of an object was mutated, and this change was visible outside the function, but the calling convention is still call-by-value. This is by definition of the C++ spec.

In the next call we use call-by-reference to pass in "a". Now we assign a new instance to "a" and mutate this. After the call, the change is seen via "a", as it prints the 0 that we assigned to the "value" member of this new instance. However, we haven't touched the instance that a en b originally pointed to. This is seen as we observe that for b the old value is printed.

It's this last effect that is impossible to achieve in Java. We can mutate the state of the object our pointer points to, but this has the side-effect that everyone else who points to that object also sees this change. If the class involved is immutable (as with a String or a Long) we cannot even do this. What we want to achieve is simply doing an assignment; assign a new pointer. If you want to do this from a function being called, you need call-by-reference. Java doesn't have call-by-reference, so it's impossible to re-assign a variable from the caller in a callee.

The output will be:Initial value:3After call by value:3After call by reference:0Try for yourself here: http://codepad.org/B0oUJuC8 In both cases pointers are being passed into the function. In both cases a new instance of A is assigned to the function parameter, and this new instance is mutated to hold the value 0. In the case of the call-by-value version, this change is not propagated to the calling main function. Before and after the call the value is still 3 and thus the a in main still points to the same instance.In the case of the call-by-reference version, the change is propagated, and the value is now 0.Now you are probably going to scream that both type of functions can mutate the instance that the A being passed into points to. So, at this point I can imagine your hands itching to write a call-by-value version that also mutates A's value to 0.This however is NOT what distinguishes call-by-refernence. Call-by-reference let's the variable being passed in point to another instance,. We often don't want to mutate the original A, since others might point to this as well, and they will be effected too.This is demonstrated by the following code:The output will be:Initial value A:3Initial value B:3After call by value A:1After call by value B:1After call by reference A:0After call by reference B:1Try this one here: http://codepad.org/Kzxxk6Hp What happens is that a new instance is created and both "a" and "b" point to it. If we pass "a" into the call-by-value function, it gets another copy of the pointer pointing to the one and only instance. There are now thus 3 pointers to it. Via this pointer that happens to live in the