2016-08-24 35 views

回答

1

展望final switch文档:http://dlang.org/spec/statement.html#FinalSwitchStatement它只是允许相同的优化与C switch(它应该在代码中设置的标签,只是使用类似转到此基础上的变量值)。 D中的switch比C中的switch更一般,并且不允许这样的优化。从D开关可以使用运行时初始化大小写值。

+0

我应该正确地解释自己,我并不是故意将D与C进行比较,虽然这是一个很好的观点,我的意思是在代码生成方面比较D'final switch和switch语句的优化可能性。 (原来的帖子后来编辑澄清) –

+0

我刚刚把D中的'final switch'和'switch'与C中的'switch'进行了比较。D中的'switch'可以使用运行时初始化的case值,所以我认为它不能实现通过标签/转到。 –

+0

我相信GDC足够智能,可以发现当“switch”的D代码恰好不比C更普遍时所有可能的优化。例如,当存在大量密集常量可能性时,它会生成跳转表。但是 –

6

简答:无。

龙答:final switch超过switch的主要优点是,当你有一个枚举类型的值使用它,它给你当你缺少枚举成员之一的错误,这样你就可以确保你有他们全部覆盖。如果枚举更改为拥有更多成员或更少成员,则您将知道需要更新switch声明。

除此之外,在语义上,一个final switch几乎是同样的事情作为switch声明与具有assert(0)一个default情况 - 它只是它抛出一个SwitchError而不是断言0。但效果基本相同 - 当switch语句被赋予一个没有被任何情况覆盖的值时,程序就会死亡。

我真的可以考虑使用final switch以外的其他任何东西的唯一原因是,当case语句应该涵盖所有可能的情况时,您不必编写default的情况。考虑到至少在某些时候,你可以提供一个更有意义的信息,而不是一个SwitchError给你(No appropriate switch clause found),我倾向于认为明确的default案例与assert(0)并且在switch语句不在枚举上运行时使用final switch

现在,关于您的优化问题,我认为final switch不会提供任何比正常switch优化的机会。当为final switch给出的case语句中未包含的值时,为了抛出SwitchErrorfinal switch将不得不被降低到正常switch语句,其中default情况会抛出SwitchError

所以,在生成的代码方面,有一个真正的final switch,并且具有抛出一个SwitchError和优化明智的一个default情况下,正常switch没有区别,final switch是类似的船到switch语句断言0(虽然assert(0)一个default情况下可能更容易导致不是抛出一个SwitchError的优化,因为编译器可以假设,当一个断言明确false程序会死,而程序可能捕获的Error和继续,即使它不应该)。

我不知道编译器是否可以做任何优化的基础上,保证default的情况下,如果它被击中程序将杀死该程序。如果可以的话,那么可以通过使用final switch获得一些优化,但是具有default情况的常规switch断言0或抛出Error将与final switch在同一条船上。所以,在这方面没有什么神奇的final switchfinal switch的魔力在于通过枚举来捕捉错误。

真的,我建议你只使用final switch当你处理一个固定值的枚举类型,这样你就可以捕捉到案件不符合枚举成员,除此之外,你只是不要使用final switch。老实说,我很惊讶地发现final switch接受除枚举之外的任何东西。

+0

SwitchError不会在释放模式下抛出(这里是关于它的讨论:https://issues.dlang.org/show_bug.cgi?id=11051)。如果没有检查,一些优化是可能的,例如参见https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49054和https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51513 – jpf