21001, "mppf", "should we adjust lifetime of call-expression temporaries in split init?", "2022-11-08T15:31:05Z"
Today, we compute deinitialization point of a temporary as:
- the end of the block, if the temporary is in a variable initialization (including split init)
- the end of the statement, otherwise
See also
- Variables — Chapel Documentation 1.28
- https://chapel-lang.org/releaseNotes/1.21/01-language.pdf slide 73
Here is a code sample showing how different cases behave:
record R {
proc deinit() {
writeln("R.deinit()");
}
}
proc returnAnR() {
return new R();
}
proc g(arg) { return 1; }
proc notSplitInit() {
writeln("starting notSplitInit");
var x = g(returnAnR()); // currently, the R is deinited at end of block
writeln("ending notSplitInit");
}
notSplitInit();
writeln();
proc splitInit() {
writeln("starting splitInit");
var x;
x = g(returnAnR()); // currently, the R is deinited at end of block
writeln("ending splitInit");
}
splitInit();
writeln();
proc assign() {
var x = 1;
writeln("starting assign");
x = g(returnAnR()); // currently, the R is deinited just after this statement
writeln("ending assign");
}
assign();
writeln();
proc notInit() {
writeln("starting notInit");
g(returnAnR()); // currently, the R is deinited just after this statement
writeln("ending notInit");
}
notInit();
writeln();
Recently, some users brought up the concern that it might be confusing that the lifetime of a subexpression (such as returnAnR() in the example or something like new shared C()) is different if it's used in an initialization context or not.
The reason that we have the current rules are
- To support slicing, where
ref slice = A[1..10];e.g., creates a temporary that needs to live to the end of the block; - To support a pattern like
f.writer().write(A)where the temporary channel is closed at the end of the statement.
There were two alternatives proposed:
- To change the rule to only be end-of-block if the temporary is used in
refinitialization. This would make the rule more focused and perhaps more similar to C++ rules. - To change the rule to apply to anything that is syntactically
=whether assignment or initialization. There is some concern that this would keep values alive unnecessarily.