在switch语句的case部分之前加上默认子句

12

在 linux/kernel/signal.c 中找到了这个。

switch (_NSIG_WORDS) {
default:
    for (i = 1; i < _NSIG_WORDS; ++i) {
        x = *++s &~ *++m;
        if (!x)
            continue;
        sig = ffz(~x) + i*_NSIG_BPW + 1;
        break;
    }
    break;

case 2:
    x = s[1] &~ m[1];
    if (!x)
        break;
    sig = ffz(~x) + _NSIG_BPW + 1;
    break;

case 1:
    /* Nothing to do */
    break;
}

也许这不是一个很好的例子,但我不明白它是如何工作的,以及是什么促使Linus把default-section放在switch语句的前面。


x = *++s &~ *++m; == x = (*(++s)) & (~(*(++m))); default:和其他的case一样,如果你不把它写在最后,你需要添加break;语句以避免相同的问题。 - Grijesh Chauhan
1个回答

16
在代码中,switch块内case标签的顺序与其执行顺序无关。如果没有任何case匹配或者从上面的case落入,那么将执行default标签。将其放在代码基础部分并不会改变这一点。
default放在第一位的一个优势是,它不可能被上面的case意外或故意地落入到default标签。这意味着如果且仅当值在switch块中没有匹配到任何case语句时,才会运行default
但要非常严谨,您仍然可以使用明确的goto命令来达到default标签。不过这种情况相当罕见。

1
不确定自己是否完全理解答案的第二部分推理。假设是落到默认情况比任何其他情况都更危险? - Ziffusion
3
@Ziffusion,推理如下:人们认为default应该只在没有匹配值时才会触发。将其放在顶部使得验证这一点变得更加直观容易。这也使得未来的新增,如果通过了default,并违反了对于default的假设,则更加显眼。请注意,我并不是说我同意这种做法,这只是其他人过去向我展示的逻辑。 - JaredPar
1
非常感谢您,@JaredPar。我一直以为switch-case的工作方式类似于 if('a'){/*something*/}else if('b'){/*something else*/} else{/*quite another*/},而default子句就像是没有带上if(...)的最后一个else语句。我认为这是C语言的一个重要方面,再次感谢您。 - Netherwire

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接