在开关块内

时间:2010-06-16 08:42:47

标签: c++ switch-statement while-loop unreachable-code

我见过以下代码,取自libb64 project。 我试图理解switch块中while循环的目的是什么 -

switch (state_in->step)
    {
        while (1)
        {
    case step_a:
            do {
                if (codechar == code_in+length_in)
                {
                    state_in->step = step_a;
                    state_in->plainchar = *plainchar;
                    return plainchar - plaintext_out;
                }
                fragment = (char)base64_decode_value(*codechar++);
            } while (fragment < 0);
            *plainchar    = (fragment & 0x03f) << 2;
    case step_b:
            do {
                if (codechar == code_in+length_in)
                {
                    state_in->step = step_b;
                    state_in->plainchar = *plainchar;
                    return plainchar - plaintext_out;
                }
                fragment = (char)base64_decode_value(*codechar++);
            } while (fragment < 0);
            *plainchar++ |= (fragment & 0x030) >> 4;
            *plainchar    = (fragment & 0x00f) << 4;
    case step_c:
            do {
                if (codechar == code_in+length_in)
                {
                    state_in->step = step_c;
                    state_in->plainchar = *plainchar;
                    return plainchar - plaintext_out;
                }
                fragment = (char)base64_decode_value(*codechar++);
            } while (fragment < 0);
            *plainchar++ |= (fragment & 0x03c) >> 2;
            *plainchar    = (fragment & 0x003) << 6;
    case step_d:
            do {
                if (codechar == code_in+length_in)
                {
                    state_in->step = step_d;
                    state_in->plainchar = *plainchar;
                    return plainchar - plaintext_out;
                }
                fragment = (char)base64_decode_value(*codechar++);
            } while (fragment < 0);
            *plainchar++   |= (fragment & 0x03f);
        }
    }

什么可以给予时间?似乎无论如何,总是开关只会执行其中一种情况。我错过了什么吗?

感谢。

3 个答案:

答案 0 :(得分:3)

像肯尼说的那样,这段代码看起来像是Duff的设备。 Here是维基百科所说的。

答案 1 :(得分:3)

虽然这是Duff的设备,但这个版本不是关于实现循环展开优化,而是实现基于Base64编码流的迭代器。所以你可以这样做:

Base64Stream stream; // the base64 data

char c;

while ((c == stream->NextChar ()) != 0)
{
  // do something with c
}

在给定的代码中,第一个切换用于跳回到先前return退出的位置,然后while(1)允许迭代循环无限地继续。但是,此功能无法防止缓冲区溢出。

在C#中,有一个更简洁的解决方案,即yield语句。

答案 2 :(得分:0)

如果是尝试实施Duff的设备,那么它可能是错位的。

请注意,对于Duff的设备,如维基百科中所述,循环是有限的,而在上面提供的代码中,它是一个无休止的循环。它完成的唯一可能性是满足(codechar == code_in + length_in)条件(尽管代码片段中的code_id和length_in是不可变的)。

我怀疑它甚至可以用作Duff的设备,即它会导致编译器进行适当的循环扩展。