| Thread overview | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 29, 2013 Const initialization issue, looking for solution | ||||
|---|---|---|---|---|
| ||||
Consider the following example: http://dpaste.dzfl.pl/a0595ddf ---- // Can throw, and we want to catch int createTheVar(); // Can also throw, but we don't want to catch it here int transform(int a); int foo() { const(int) i; try { i = createTheVar(); // Clearly not allowed } catch(Exception e) // For demo purposes { // Exception handling code } return transform(i); } ---- I need to be able to catch an exception that may have been thrown during the initialization of `i`, but still have `i` be const. I can't omit the variable because I *don't* want to accidentally catch anything that transform() may have thrown. Note that the simple type const(int) is an example. This is actually in highly generic code and the type may have mutable indirection. Here's the real-world code: https://github.com/JakobOvrum/LuaD/blob/master/luad/conversions/functions.d#L86 The particular problematic type I happened to encounter for RetType is the const(CacheInfo)[5] return type of core.cpuid.dataCaches: http://dlang.org/phobos/core_cpuid.html#.dataCaches Specifics aside, I believe this is a very general problem. ---- Of course, if D had well-defined, local flow analysis like many other modern languages (e.g. C#), this code would not have to be rejected. I think that's a discussion for the future though; right now it would be nice to have a workable, general solution/workaround to the issue of initializing const/immutable variables in try-blocks. Any help is much appreciated. | ||||
May 29, 2013 Re: Const initialization issue, looking for solution | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jakob Ovrum | Why something like this is not usable?
-----------------------
int tmp;
try
{
tmp = ...;
}
catch(..)
{
}
const(int) i = tmp;
-----------------------
Not really pretty but nothing crazy.
| |||
May 29, 2013 Re: Const initialization issue, looking for solution | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Dicebot | P.S. For const reference types we have Rebindable in std.typecons AFAIR | |||
May 29, 2013 Re: Const initialization issue, looking for solution | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Wednesday, 29 May 2013 at 12:40:39 UTC, Dicebot wrote:
> Why something like this is not usable?
> -----------------------
> int tmp;
> try
> {
> tmp = ...;
> }
> catch(..)
> {
> }
> const(int) i = tmp;
> -----------------------
> Not really pretty but nothing crazy.
const(int) i = tmp; // fails when the type has mutable indirection.
| |||
May 29, 2013 Re: Const initialization issue, looking for solution | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Wednesday, 29 May 2013 at 12:42:11 UTC, Dicebot wrote:
> P.S. For const reference types we have Rebindable in std.typecons AFAIR
I can't imagine how it would work with non-class and non-interface references, like references embedded in const struct instances or const static arrays of such structs.
| |||
May 29, 2013 Re: Const initialization issue, looking for solution | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jakob Ovrum | On Wednesday, 29 May 2013 at 12:43:46 UTC, Jakob Ovrum wrote:
> const(int) i = tmp; // fails when the type has mutable indirection.
Ah, I understand that know. Well, until flow analysis is here I am afraid you can't really do anything better than assumeUnique or similar utility function.
| |||
May 29, 2013 Re: Const initialization issue, looking for solution | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Wednesday, 29 May 2013 at 12:54:24 UTC, Dicebot wrote:
> Ah, I understand that know. Well, until flow analysis is here I am afraid you can't really do anything better than assumeUnique or similar utility function.
I'm hoping there's a way to restructure the code so it works (making it more functional or whatever), but I can't for the life of me think of a way :<
Maybe leveraging another function, hopefully a Phobos function (like std.exception ones), can solve the issue neatly...
| |||
May 29, 2013 Re: Const initialization issue, looking for solution | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jakob Ovrum | On Wednesday, 29 May 2013 at 12:43:46 UTC, Jakob Ovrum wrote:
> On Wednesday, 29 May 2013 at 12:40:39 UTC, Dicebot wrote:
>> Why something like this is not usable?
>> -----------------------
>> int tmp;
>> try
>> {
>> tmp = ...;
>> }
>> catch(..)
>> {
>> }
>> const(int) i = tmp;
>> -----------------------
>> Not really pretty but nothing crazy.
>
> const(int) i = tmp; // fails when the type has mutable indirection.
I guess the first assignment of a variable should be considered as a declaration unless it has been read in between. This is the same problem as immutable constructor, and also relate to extra copies elimination.
| |||
May 29, 2013 Re: Const initialization issue, looking for solution | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jakob Ovrum | On Wednesday, 29 May 2013 at 12:36:19 UTC, Jakob Ovrum wrote:
> I need to be able to catch an exception that may have been thrown during the initialization of `i`, but still have `i` be const. I can't omit the variable because I *don't* want to accidentally catch anything that transform() may have thrown.
>
> Note that the simple type const(int) is an example. This is actually in highly generic code and the type may have mutable indirection.
Fundamental issue here is that
const T t;
is almost useless, it is essentially immutable since you cannot change it and you cannot alias it. As such, it probably should be changed to a mutable object or an immutable one.
However, since const/mutable aliasing is allowed, you can do:
union U (T)
{
const T ct;
T mt;
}
because const doesn't mean that object would never change, you can mutate it through alias. From the opposite view, there is also no problem in reinterpeting a mutable object as const object (since mutables can be converted to const).
Depending on your mutable indirection situation this can work or may not.
| |||
May 29, 2013 Re: Const initialization issue, looking for solution | ||||
|---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On Wednesday, 29 May 2013 at 13:19:34 UTC, deadalnix wrote:
> I guess the first assignment of a variable should be considered as a declaration unless it has been read in between. This is the same problem as immutable constructor, and also relate to extra copies elimination.
Yeah, and languages like C# solve these problems quite beautifully. I don't think there's a reason we can't do almost the same thing in D, except it requires implementation effort and overcoming Walter's protests. Regardless, it's probably not something to expect in the short-term.
----
I was unable to leverage std.exception. collectException looks promising at first glance - and maybe if the return value and out parameter were switched, it would work - but then I suspect the function's implementation would face exactly the same problem.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply