Generating switch at Compile Time

Stefan Koch via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Apr 17 21:42:57 PDT 2017


On Thursday, 13 April 2017 at 21:06:52 UTC, Jesse Phillips wrote:
> I realize that this is likely really pushing the compile time 
> generation but a recent change to the switch statement[1] is 
> surfacing because of this usage.
>
> uninitswitch2.d(13): Deprecation: 'switch' skips declaration of 
> variable uninits
> witch2.main.li at uninitswitch2.d(14)
>
> ---------------------
>     import std.traits;
>     import std.typecons;
>     import std.meta;
>
>     private static immutable list = AliasSeq!(
>             tuple("a", "q"),
>             tuple("b", "r"),
>             );
>
>     void main() {
>         import std.stdio;
>         string search;
>         switch(search) {
> --->        foreach(li; list) { // li initialization is skipped
>                 mixin("case li[0]:");
>                 mixin("writeln(li[1]);");
>                 return;
>             }
>             default:
>             break;
>         }
>
>         // Works
>         mixin(genSwitch("search"));
>     }
> ---------------------
>
> I realize I can build out the entire switch and mix it in:
>
> ---------------------
>     string genSwitch(string search) {
>         auto ans = "switch(" ~ search ~ ") {\n";
>             foreach(li; list) {
>                 ans ~= "case \"" ~ li[0] ~ "\":\n";
>                 ans ~= "writeln(\"" ~ li[1] ~ "\");\n";
>                 ans ~= "return;\n";
>             }
>             ans ~= "default:\n";
>             ans ~= "break;\n";
>         ans ~= "}";
>
>         return ans;
>     }
> ---------------------
>
> But I'm just wondering if the new initialization check should 
> not be triggered from this utilization.
>
> ---------------------
>     // Unrolled based on
>     // 
> https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time description
>
>     version(none)
>     void func2243(Tuple param0, Tuple param1) {
>         {
>             {
>                 case param0[0]:
>                 writeln(param0[1]);
>                 return;
>             }
>             {
>                 case param1[0]:
>                 writeln(param1[1]);
>                 return;
>             }
>         }
>     }
> ---------------------
>
> Thoughts?
>
> 1. https://issues.dlang.org/show_bug.cgi?id=14532

This is what is generated by your example:

         switch (search)
         {
                 unrolled {
                         { // does not actually open a new scope
                                 immutable 
immutable(Tuple!(string, string)) li = __list_field_0;
                                 case "a":
                                 {
                                 }
                                 writeln(li.__expand_field_1);
                                 return 0;
                         }
                         {  // same here we do not actually open a 
new scope.
                                 immutable 
immutable(Tuple!(string, string)) li = __list_field_1;
                                 case "b":
                                 {
                                 }
                                 writeln(li.__expand_field_1);
                                 return 0;
                         }
                 }
                 default:
                 {
                         break;
                 }
         }
         return 0;


it should be clear to sww why li's initialisation is referred to 
as skipped.



More information about the Digitalmars-d-learn mailing list