03.11.2011 11:29, kenji hara пишет:

EnumMember returns tuple, it is compile-time sequence.
And foreach with tuple unrolls its body. Then, Loop A is unrolled like follows.

__foreachEntry0: {
   if ( TestEnum.ONE == TestEnum.TWO )
     goto __foreachEntry1;
   writeln( "A: ", TestEnum.ONE );
}
__foreachEntry1: {
   if ( TestEnum.TWO == TestEnum.TWO )
     goto __foreachEntry2;
   writeln( "A: ", TestEnum.TWO );  // LineX
}
__foreachEntry2: {
   if ( TestEnum.THREE == TestEnum.TWO )
     goto __foreachEntry3;
   writeln( "A: ", TestEnum.THREE );
}
__foreachEntry3: {
   if ( TestEnum.FOUR == TestEnum.TWO )
     goto __foreachEntry4;
   writeln( "A: ", TestEnum.FOUR );
}
__foreachEntry4:
   ;

And, when member == TestEnum.TWO, the LineX is not reachable.

With loop B, unrolling is similar, but dmd does not warn the
unreachable else block.
Because dmd treats it as that is stated by programmers as "may become
unreachable branch".
(This is reasonable assumption, sometimes the condition of if
statement folded to constant.)

With loop C, list is "tuple of local variable symbols", it is similar
to follows.

auto __list0 = TestEnum.ONE;
auto __list1 = TestEnum.TWO;
auto __list2 = TestEnum.THREE;
auto __list3 = TestEnum.FOUR;
alias TypeTuple!(list0, list1, list2, list3) list;

list itself is compile time tuple, but its elements are evaluated at
runtime. Loop C is unrolled like A and B, but the conditions are
evaluated at runtime, then compiler does not warn the branches as
unreachable.

Kenji Hara

Wow... Indeed. Excellent answer. Just like an article from documentation. Thanks, it's usable for me too.

Reply via email to