Bug 11988 – Add __switch symbol to allow retrieval of switch statement value
Status
RESOLVED
Resolution
DUPLICATE
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-01-24T12:53:00Z
Last change time
2014-01-29T00:29:57Z
Assigned to
nobody
Creator
andrej.mitrovich
Comments
Comment #0 by andrej.mitrovich — 2014-01-24T12:53:42Z
Often you would want to use the value of the switch statement, but the only way to do this is to store the value to a variable first. This has the unfortunate effect of invading the outer scope:
-----
import std.string;
int get() { return 0; }
void a(int) { }
void b(int) { }
void c(int) { }
void main()
{
int v = get();
switch (v)
{
case 1: a(v); break;
case 2: b(v); break;
case 3: c(v); break;
default:
assert(0, format("Unhandled case %s", v));
}
// problem: v is still visible here
}
-----
To avoid invading the outer scope, but at the same time avoiding introduction of arbitrary language features, it might be useful to introduce another compiler-reserved symbol "__switch". The above code would then look like:
-----
import std.string;
int get() { return 0; }
void a(int) { }
void b(int) { }
void c(int) { }
void main()
{
switch (get())
{
case 1: a(__switch); break;
case 2: b(__switch); break;
case 3: c(__switch); break;
default:
assert(0, format("Unhandled case %s", __switch));
}
}
-----
The default diagnostic is where I've encountered a need for this feature, very frequently too.
Comment #1 by monkeyworks12 — 2014-01-24T13:30:21Z
(In reply to comment #0)
> Often you would want to use the value of the switch statement, but the only way
> to do this is to store the value to a variable first. This has the unfortunate
> effect of invading the outer scope:
>
> -----
> import std.string;
>
> int get() { return 0; }
>
> void a(int) { }
> void b(int) { }
> void c(int) { }
>
> void main()
> {
> int v = get();
> switch (v)
> {
> case 1: a(v); break;
> case 2: b(v); break;
> case 3: c(v); break;
>
> default:
> assert(0, format("Unhandled case %s", v));
> }
>
> // problem: v is still visible here
> }
> -----
>
> To avoid invading the outer scope, but at the same time avoiding introduction
> of arbitrary language features, it might be useful to introduce another
> compiler-reserved symbol "__switch". The above code would then look like:
>
> -----
> import std.string;
>
> int get() { return 0; }
>
> void a(int) { }
> void b(int) { }
> void c(int) { }
>
> void main()
> {
> switch (get())
> {
> case 1: a(__switch); break;
> case 2: b(__switch); break;
> case 3: c(__switch); break;
>
> default:
> assert(0, format("Unhandled case %s", __switch));
> }
> }
> -----
>
> The default diagnostic is where I've encountered a need for this feature, very
> frequently too.
Why don't we just allow `auto var = <expression>`, like in an if-statement?
Comment #2 by andrej.mitrovich — 2014-01-24T13:56:44Z
(In reply to comment #1)
> Why don't we just allow `auto var = <expression>`, like in an if-statement?
Because they would have different semantics. The if statement's body is not entered when the expression implicitly converts to false, e.g.:
-----
void main()
{
if (auto x = 0) { assert(0); } // body not entered
if (auto x = 1) { }
}
-----
-----
With a switch you wouldn't want this to happen. For example:
void main()
{
switch (auto x = 0)
{
case 0: // this must continue to work.
}
}
-----
So you'd end up with different semantics.
Comment #3 by yebblies — 2014-01-24T18:12:50Z
(In reply to comment #2)
> (In reply to comment #1)
> > Why don't we just allow `auto var = <expression>`, like in an if-statement?
>
> Because they would have different semantics. The if statement's body is not
> entered when the expression implicitly converts to false, e.g.:
>
> [snip]
>
> So you'd end up with different semantics.
Who would expect 'if' and 'switch' to have the same semantics?
I don't think this is worth adding a magic symbol (nested switch statements?) but switch(auto a = b) solves this quite nicely.
Comment #4 by andrej.mitrovich — 2014-01-25T11:28:37Z
(In reply to comment #3)
> Who would expect 'if' and 'switch' to have the same semantics?
Well, consistency is king. And you may introduce a bug without noticing if during refactoring you change a switch statement into an if statement.
__switch might seem a bit obscure though from the way it looks.. If the different semantics of "if (auto x = ..)" and "switch (auto x = ..)" isn't really a big issue then I'm all for it.
Comment #5 by andrej.mitrovich — 2014-01-29T00:29:57Z
Just realized I already have a request to allow a declaration in the switch statement, Issue 11070.
*** This issue has been marked as a duplicate of issue 11070 ***