digitalmars.D.learn - Switch constants
- bearophile (28/28) Nov 13 2010 In a not-ranged cases body, like in the program below (that doesn't comp...
- Dmitry Olshansky (5/33) Nov 13 2010 Well, there is fall-through ;) And there still could be goto's.
- Daniel Murphy (63/66) Nov 13 2010 In switch statements, you can do stuff like:
- bearophile (4/12) Nov 13 2010 You are right. Thank you for all the answers.
- Stanislav Blinov (5/42) Nov 13 2010 I would say that while bar may be CTFE'd, it is nevertheless a function
- BCS (7/27) Nov 14 2010 If you want exactly that:
In a not-ranged cases body, like in the program below (that doesn't compile), the switch variable is a compile-time constant, so why doesn't the compile see x as constant there? template Foo(uint x) { static if (x <= 1) enum Foo = 1; else enum Foo = x * Foo!(x - 1); } int bar(uint x) { switch (x) { case 0: return Foo!x; case 1: return Foo!x; case 2: return Foo!x; case 3: return Foo!x; case 4: return Foo!x; default: return -1; } } void main() { assert(bar(4) == 24); } That code works if I replace lines like: case 2: return Foo!x; With: case 2: return Foo!2; But when the code isn't DRY bugs may happen... (There are ten different better ways to write that program, but this is not the point). Bye, bearophile
Nov 13 2010
On 14.11.2010 1:21, bearophile wrote:In a not-ranged cases body, like in the program below (that doesn't compile), the switch variable is a compile-time constant, so why doesn't the compile see x as constant there?Well, there is fall-through ;) And there still could be goto's. In essence "case x:" is nothing but a glorified local label.template Foo(uint x) { static if (x<= 1) enum Foo = 1; else enum Foo = x * Foo!(x - 1); } int bar(uint x) { switch (x) { case 0: return Foo!x; case 1: return Foo!x; case 2: return Foo!x; case 3: return Foo!x; case 4: return Foo!x; default: return -1; } } void main() { assert(bar(4) == 24); } That code works if I replace lines like: case 2: return Foo!x; With: case 2: return Foo!2; But when the code isn't DRY bugs may happen... (There are ten different better ways to write that program, but this is not the point). Bye, bearophile-- Dmitry Olshansky
Nov 13 2010
"bearophile" <bearophileHUGS lycos.com> wrote in message news:ibn320$2ucs$1 digitalmars.com...In a not-ranged cases body, like in the program below (that doesn't compile), the switch variable is a compile-time constant, so why doesn't the compile see x as constant there?In switch statements, you can do stuff like: switch(x) { case 0: case 1: // what is x here? break; } switch(x) { case 0: break; // what is x here? case 1: goto case 0: } goto label1; switch(x) { case 0: label1: break; // what is x here? } switch(x) { case 0: x = y; break; // what is x here? } As far as I know, NONE of the constructs in d allow you to treat a run-time variable as if it was compile-time constant. I doubt this would be possible without flow analysis. You can however do something like this (if you must) template Foo(uint x) { static if (x <= 1) enum Foo = 1; else enum Foo = x * Foo!(x - 1); } int getv(int x) { switch(x) { foreach(i; TypeTuple!(0, 1, 2, 3, 4, 5, 6)) { case i: return Foo!i; } } assert(0); } where the switch expands out to switch(x) { case 0: return Foo!0; case 1: return Foo!1; case 2: return Foo!2; case 3: return Foo!3; case 4: return Foo!4; case 5: return Foo!5; case 6: return Foo!6; } Is this DRY enough for you?
Nov 13 2010
Daniel Murphy:switch(x) { case 0: break; // what is x here? case 1: goto case 0: } etcYou are right. Thank you for all the answers. Bye, bearophile
Nov 13 2010
bearophile wrote:In a not-ranged cases body, like in the program below (that doesn't compile), the switch variable is a compile-time constant, so why doesn't the compile see x as constant there? template Foo(uint x) { static if (x <= 1) enum Foo = 1; else enum Foo = x * Foo!(x - 1); } int bar(uint x) { switch (x) { case 0: return Foo!x; case 1: return Foo!x; case 2: return Foo!x; case 3: return Foo!x; case 4: return Foo!x; default: return -1; } } void main() { assert(bar(4) == 24); } That code works if I replace lines like: case 2: return Foo!x; With: case 2: return Foo!2; But when the code isn't DRY bugs may happen... (There are ten different better ways to write that program, but this is not the point). Bye, bearophileI would say that while bar may be CTFE'd, it is nevertheless a function that can be called at runtime, in which case x may no longer be a compile-time constant. So there is little compiler can do except for refusing such code.
Nov 13 2010
Hello bearophile,In a not-ranged cases body, like in the program below (that doesn't compile), the switch variable is a compile-time constant, so why doesn't the compile see x as constant there? template Foo(uint x) { static if (x <= 1) enum Foo = 1; else enum Foo = x * Foo!(x - 1); } int bar(uint x) { switch (x) { case 0: return Foo!x; case 1: return Foo!x; case 2: return Foo!x; case 3: return Foo!x; case 4: return Foo!x; default: return -1; } }If you want exactly that: switch(x) { foreach(X; Tuple!(0,1,2,3,4)) { case X: return Foo!X; } }
Nov 14 2010