How to initialize immutable variables with an expression that throws an exception to catch?
Steven Schveighoffer
schveiguy at gmail.com
Fri Apr 3 14:12:06 UTC 2020
On 4/3/20 9:21 AM, Atila Neves wrote:
> On Friday, 3 April 2020 at 06:56:27 UTC, FeepingCreature wrote:
>> Consider the following code:
>>
>> struct S { }
>> ...
>> S s = void;
>> try
>> s = fun();
>> catch (Exception)
>> return;
>> call(s);
>>
>> Now you change S to be immutable.
>>
>> How are you supposed to initialize s? You can't assign to it anymore.
>>
>> Assume that we explicitly don't want to pull the call into the try
>> body, for instance because we want exceptions from call to not be caught.
>>
>> The only way I've found is to make fun() return Algebraic!(S,
>> Exception) but that's kind of ugly and bypasses a basic language feature.
>>
>> Maybe D could allow to initialize an immutable variable from the try{}
>> body if the catch{} body is statically known to exit by return/throw?
>
> --------------------
> immutable struct S { }
>
> void main() {
> S impl() {
> try
> return fun();
> catch (Exception) {
> S s = void;
> return s;
> }
> }
>
> call(impl);
> }
>
>
> void call(S s) {
>
> }
>
> S fun() {
> return S();
> }
>
> --------------------
That's not the same. The original code does not call `call` with a
void-initialized S.
However, this might do the trick:
void main() {
bool voided = false;
S impl() {
try
return fun();
catch (Exception) {
voided = true;
S s = void;
return s;
}
}
auto s = impl();
if(!voided) call(s);
}
But there is a catch here. Assigning an S to a void-initialized S is
still copying stuff. It's not the same as never touching that memory.
-Steve
More information about the Digitalmars-d
mailing list