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 ***