C++中switch语句中case之前的if语句

8

我被委派为公司重写一些旧软件,发现源代码中有一个有趣的结构。

switch(X){
    if(Y==Z){
       case A: ... break;
       case B: ... break;
    }
    case C: ... break;
    default: ...;
}

编译器警告我,if语句内的代码将不会被执行,但在测试时似乎if语句没有被验证,然而case语句却是被验证了。
可能有一些原因,比如早期的C ++编程时期,因为其中一些代码已经超过20年了,你会写出这样的结构吗?由于它在生产代码中,所以它似乎确实会做一些事情?
如果您知道这样做的原因,并且编译器似乎可以忽略它,请告诉我。谢谢!
编辑:这种情况发生了多次,因此它似乎不是一个简单的错误。这就是让我感到困惑的地方。
编辑2:这里是我用于测试的示例。我不确定它是否有帮助,不过原始代码位于一个包含1200行的怪兽函数中,因此从中创建一个测试用例基本上是不可能的。
for (int i=0; i<5;i++)
{
    switch(i)
    {
        if (i==0 || i ==1)
        {
            cout << "reached before case";
            case 0: cout << "inside case 0" << std::endl; break;
            case 1: cout << "inside case 1" << std::endl; break;
            case 2: cout << "inside case 2" << std::endl; break;
        }
        case 3: cout << "inside case 3" << std::endl; break;
        default: cout << "inside default" << std::endl;
    }
}

3
它真的是在开关中的“第一件事”吗? - StoryTeller - Unslander Monica
3
if语句没有起到任何作用。在过去可能会有一些作用,比如之前有一个case语句但后来被移除了。如果你正在使用git或svn等版本控制工具,可以尝试通过"blame"命令查找代码,找出是谁编写的,然后询问他们的意图。 - François Andrieux
1
这些文件有编辑历史记录吗?我猜 ifswitch 更早存在。但是,switch 在这方面的行为非常类似于 goto,即使在旧版本的 C++ 中也是如此。该代码要求 Y==Z 可以编译,但比较在运行时从未进行。 - Drew Dormann
8
switch语句中可以用一些奇怪的结构,比如Duff's device。这可能是一种优化尝试,但在我看来同样有可能只是一个旧的bug(在语法上有效,但在语义上不正确),而较老的编译器没有发出警告。 - 0x5453
2
根据您在Edit2中的代码,我强烈怀疑这段代码的作者既不理解也没有测试过这段代码。既然您已经被分配了重写任务,我建议找到将逻辑从该函数中提取到更小、可测试的函数的方法。 - Drew Dormann
显示剩余6条评论
1个回答

4
有没有任何理由可以解释为什么会写出那样的结构?
只有作者自己知道原因(甚至他们自己都可能不知道)。如果有源代码版本控制元数据可用,相关提交消息可能有用。没有更多信息,我们只能猜测他们当时在想些什么。以下是一些可能的答案:
- 作者认为if语句的条件会产生某些影响,但他们错了,这个错误没有被测试。 - 这是一些重构的遗留结果。 - 可能删除了一些使用该语句的代码,使该语句失去了意义。 - 或者它从其他地方复制过来,原本是有意义的。 - 或者曾经有一系列if语句,有意愿将它们替换为switch,但更改只进行了一半。

没有提交历史记录,也没有文档,只有一个包含所有源代码的文件夹。所以我猜我永远不会知道为什么要这样做,而且我非常怀疑这段代码是否经过测试。我认为它只是被放入客户系统中并在那里进行了测试。但如果这个结构没有任何用处,那么我可以停止寻找更深层次的意义,只接受它是一个错误。谢谢。 - nuclear

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