1

我看过以下代码,取自libb64 项目。我试图了解 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);
        }
    }

有什么可以给的呢?似乎无论如何,交换机总是只会执行其中一种情况。我错过了什么?

谢谢。

4

3 回答 3

3

正如 Kenny 所说,这段代码看起来像 Duff 的设备。 是维基百科所说的。

于 2010-06-16T08:57:44.030 回答
3

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

Base64Stream stream; // the base64 data

char c;

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

在给定的代码中,我们使用的第一个开关跳回到前一个return退出的位置,然后 while (1) 允许迭代循环无限期地继续。但是,此函数中没有针对缓冲区溢出的保护。

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

于 2010-06-16T09:22:39.670 回答
0

如果这是实现 Duff 设备的尝试,那么它可能放错了位置。

请注意,对于 Duff 的设备,如 Wikipedia 中所述,循环是有限的,而在上面显示的代码中,它是一个永无止境的循环。它完成的唯一可能性是满足 (codechar == code_in+length_in) 条件(不过,code_id 和 length_in 在代码片段中是不可变的)。

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

于 2010-06-16T09:12:25.110 回答