Take the 2-minute tour ×
Computer Science Stack Exchange is a question and answer site for students, researchers and practitioners of computer science. It's 100% free, no registration required.

From my Googling, it appears that call by value-result is similar to call by reference in that it changes values in the caller, but it's different in that the changes don't take place until the callee exits, and that if the same variable is passed as more than one argument, it'll be treated as separate values in the callee instead of the same value as in call by reference.

Neither fact helps me explain why call by value-result produces different output than call by reference in the following code:

program Param (input, output); 
var
  a, b: integer;
  procedure p (x, y : integer); 
  begin
    x := x + 2 ; 
    a := x * y ; (1)
    x := x + 1   (2)
  end; 
begin
  a := 1 ;
  b := 2 ;
  p (a, b) ; 
  writeln (a)
end.

Edit: here's my understanding of things: The insight here is that in CBR, in line (1), both a and x point to the same thing, so assigning to a updates both a and x to x * y which is 6. But in CBVR, a and x point to different things, so line 1 only updates a to 6. x remains 3. Then CBR updates a right away so a ends up being 7 outside p. But CBVR updates a to whatever x is at the end of p, which is 4, so even though a was 6 in line (1), after p exits it's changed to 4.

share|improve this question
    
Is a meant to be a global variable in your code? –  Joe Nov 8 '12 at 4:18
    
The code is meant to be Pascal style, so I assume yes. –  Tootsie Rolls Nov 8 '12 at 4:34
    
Do people still think in terms call by value and call by reference? –  Andrej Bauer Nov 13 '12 at 13:15
add comment

3 Answers

up vote 3 down vote accepted

EDIT:
An addendum: if you want to "simulate" call by value-result in Pascal (or in another language that supports only call by reference); you can use this trick:

procedure p(var x, y : Integer); // simulates call by value-result
var
  xtmp, ytmp : Integer;

  procedure p_hidden(var x, y : Integer); // nested "hidden" procedure
  begin
  ... YOUR ORIGINAL CODE HERE ...
  end;

begin
  xtmp := x; ytmp := y; // use auxiliary variables
  p_hidden(xtmp,ytmp);  // call by ref the nested procedure
  x := xtmp; y := ytmp; // copy values before return 
end;

A simple method to "visualize" what is happening, is "inserting" the procedure in the point where it is called:

CALL BY REFERENCE:

a := 1; b := 2;   
p(a, b)
//// procedure p (var x, y : integer);
//// x is the same as a, y is the same as b
//// begin 
  a := a + 2 ;  // a = 3
  a := a * b ;  // a = 3 * 2 = 6
  a := a + 1    // a = a + 1 = 7
//// end; 
writeln (a)     // prints 7

CALL BY VALUE-RESULT:

a := 1; b := 2;  
p(a, b)
//// procedure p (valres x, y : integer); // by value result
//// x is the same as a, y is the same as b like in a by reference call
  xt := a; yt := b;  // xt and yt are two "new" variables
  //// begin 
  xt := xt + 2 ;  // xt = 3
  a := xt * yt ;  // a = 3 * 2 = 6
  xt := xt + 1    // xt = 3 + 1 = 4
//// end;  
//// the values of xt and yt are copied back to a and b (x and y) before return
  a := xt;       // a = 4
  b := yt;       // b = 2
writeln (a)      // prints 4
share|improve this answer
    
The question was about value-result. You need to put back x and y in a and b at end of p. –  AProgrammer Nov 8 '12 at 13:51
    
@AProgrammer: thanks, I completely missed the "-result" part :-( and to be honest I didn't remember that form of passing parameters at all); I updated the answer. –  Vor Nov 8 '12 at 14:04
1  
... definitely too much code here :( ... –  Vor Nov 8 '12 at 19:17
1  
I think you can reduce the ratio of code by explaining the concepts shortly. –  Raphael Nov 9 '12 at 7:59
add comment

I'm not very familiar with Pascal, but there are some scoping issues.

The 2nd line of p modifies global variable a. When you pass by reference, line 1 of p also modifies x which is the same as global a. When you pass by value, line 1 does not modify global a, but line 2 still does, using the local value of x, which is global a + 2.

If you can, using a debugger to actually step through code like this can be very instructive.

share|improve this answer
    
I'd like to, but Pascal doesn't have call by value-result (this code sample is hypothetical). –  Tootsie Rolls Nov 8 '12 at 6:50
    
I think your current definition of p uses call by value; using "procedure p(var x, y: integer);" switches to call by reference, so if I'm not mistaken you should be able to test both cases. –  Mike B. Nov 8 '12 at 8:13
add comment

Using the variables are boxes analogy.

//a := 1

|   1   | <-- Variable a, with holding the value 1
|_______| 

procedure f(x: Integer)...

Call by value: On a call f(a), the value of a is loaded (copied into the function f's very own box x. It receives a copy of the value.

    //f(a)

 a -> |   1   | -- copying -->  |   1   | <- x
      |_______|                 |_______| 

Here, there are two boxes.


Call by reference: In this case, f doesn't get its own box. Instead, you tell f what box to work with: In this case, the box called a.

    //f(a)

 a -> |   1   | <- x -- for the duration of the call f(a)
      |_______| 

As you can see, there is only one box, but it now has two names.

I lied to you, initially. A variable isn't a box, it's just a name for one.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.