principleMinor
Call by value-result vs. call by reference?
Viewed 0 times
callresultreferencevalue
Problem
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:
Edit: here's my understanding of things:
The insight here is that in CBR, in line (1), both
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.Solution
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:
A simple method to "visualize" what is happening, is "inserting" the procedure in the point where it is called:
CALL BY REFERENCE:
CALL BY VALUE-RESULT:
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 7CALL 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 4Code Snippets
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 := 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 7a := 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 4Context
StackExchange Computer Science Q#6549, answer score: 5
Revisions (0)
No revisions yet.