1

我知道这之前已经讨论过了,我已经阅读了我能找到的关于 switch 的所有问题和答案。我的问题不是关于 Duff 设备的语法或功能,而是关于 switch,这恰好很好地说明了这个问题。

    {
    int n = (count + 7) / 8;

    switch(count % 8) {
        case 0: do { *to++ = *from++;
        case 7: *to++ = *from++;
        case 6: *to++ = *from++;
        case 5: *to++ = *from++;
        case 4: *to++ = *from++;
        case 3: *to++ = *from++;
        case 2: *to++ = *from++;
        case 1: *to++ = *from++;
        } while(--n > 0);
    }

我理解这样做,n 的值随着每次迭代而递减。我也明白宽松的编译器规则允许其他情况跳入 do 循环(很奇怪,但我理解)

但是由于 switch 语句是 (count % 8) 的函数,并且没有任何变化或作用于 count 的值,为什么 count 首先会发生变化以在 switch 内产生不同的模余数?

假设 (count % 8) 在第一遍产生 7。处理完案例 7:count 的值保持不变,因此 (count % 8) 的值应该保持不变,因此案例 6:不应该为真,任何其他情况也不应该是没有默认值的 n 应该递减,并且do 循环的下一次迭代应该以 count 的值不变开始。所以看起来循环会结束到 0,count 永远不会改变,所以它只会执行 case 7,每次通过都使所有其他代码毫无意义。

但如果这是真的,那么 Duff 的设备将无法工作,因为它显然依赖于 int(n + 7)/8 来为每个 count 值产生 8 次重复 n 值,并且与 (count % 8) 配对意味着 count 确实是递减以产生一个在 7 和 0 之间递减的模余数循环。

从我的新手的角度来看,这似乎需要一个 --count 在那个循环中的某个地方。所以我的结论是我不明白 switch 是如何工作的。我会很感激任何解释。

4

1 回答 1

0

在对各种版本进行了一些测试之后,我可以肯定地说 count 没有改变值,只有 n 改变了值。当然,这意味着在 do:while 中简单地连续执行 8 次赋值,原始代码在没有 switch 的情况下可以完全一样地工作.

至于开关是如何工作的,我通过测试发现它基本上按我的预期工作,除了它执行每个案例而不考虑值,除非你在每个案例中都包含一个中断。进一步的证据表明 count 没有改变,因此 Duff 的代码中没有中断,再加上 count 的值不变,进一步支持了切换完全没有意义的断言。

这将产生完全相同的结果;

{
//integer division by 8 produces 8 iterations of the same value
int n = (count + 7) / 8; 

do {
    *to++ = *from++; //therefore since the loop will be 1/8th
    *to++ = *from++;
    *to++ = *from++; //the value of count you need to perform 
    *to++ = *from++;
    *to++ = *from++; //8 assignments per iteration of n
    *to++ = *from++;
    *to++ = *from++; //this produces the same result without
    *to++ = *from++;
    *to++ = *from++; //the switch
} while(--n > 0);

}   
于 2016-02-15T18:48:45.333 回答