默认在开关块的开头

时间:2012-02-06 22:15:24

标签: c++ coding-style

在浏览解析器的代码时,例如Parser.cpp里面clang编译器的clang / Parse目录

switch (Close) {
default: break;
case tok::r_paren : LHSName = "("; DID = diag::err_expected_rparen; break;
case tok::r_brace : LHSName = "{"; DID = diag::err_expected_rbrace; break;
case tok::r_square: LHSName = "["; DID = diag::err_expected_rsquare; break;
case tok::greater:  LHSName = "<"; DID = diag::err_expected_greater; break;
case tok::greatergreatergreater:
                    LHSName = "<<<"; DID = diag::err_expected_ggg; break;
}

我看到default刚开始。是否有任何理由保持这种方式。通常我们会将default保留在最后,所以我有点困惑。

2 个答案:

答案 0 :(得分:1)

只要您添加了break s。

,订单就没有任何区别

顺便说一句,我希望在每个breakcase 之前立即将<{1}}放在之前。验证遵循此规则比尝试展望每个案例陈述的结尾要容易得多。

default

如果您将switch (Close) { break; default: break; case tok::r_paren : LHSName = "("; DID = diag::err_expected_rparen; break; case tok::r_brace : LHSName = "{"; DID = diag::err_expected_rbrace; break; case tok::r_square: LHSName = "["; DID = diag::err_expected_rsquare; break; case tok::greater: LHSName = "<"; DID = diag::err_expected_greater; break; case tok::greatergreatergreater: LHSName = "<<<"; DID = diag::err_expected_ggg; } 解释为“请勿通过进入此案例来自任何其他情况。”,您可能会更容易理解这一点“不要通过这个案例落入任何后续案例。”

在这种布局中,很容易看出是否缺少break,因此迫使作者(和读者)问他/她“我想要在这里进行跟进吗?”。所有的break都很好地排队,如果缺少一个就很明显。

澄清:我的回答中没有“魔力”。我只是以一种对我来说更易读的方式放置我的空白。空白并不重要,因此我可以自由地做到这一点。 break最后的break是多余的。如果缺少,则不允许编译器循环到switch的顶部,就好像它是某种switch循环一样。同样,while开头的冗余break不会发生任何变化,编译器必须接受(并忽略)。

答案 1 :(得分:0)

我唯一一次看到默认事项的位置就是做这样的事情,这是Duff's Device类型的构造,应该永远不会在现代平台上尝试。 :)


void copyAligned4Bytes(u32 *in, u32 *out, int numBytes)
{
  assert((numBytes & 0x03) == 0);

  while(numBytes)
  {
    switch(numBytes)
    {
      default: *out++ = *in++; numBytes -= 4;
      case 12: *out++ = *in++; numBytes -= 4;
      case 8: *out++ = *in++; numBytes -= 4;
      case 4: *out++ = *in++; numBytes -= 4;
    }
  }
}

啊,在C中编码的乐趣尽可能接近汇编程序以获得某种类型的跳转表。