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