0

我当前的代码中有一个错误,几天来我一直在努力解决这个问题。我将在下面发布代码的摘要版本(不是我的实际代码,但它仍然可以编译)。

#include <iostream>

using namespace std;

int main()
{
  int x = 7;

  switch(x)
  {
    case 1:
    {
      case 2:
      cout << "hi";
    }
  }
}

我有时喜欢在我的 switch case 中引入更严格的范围,这样局部变量名就不会干扰我之前使用的变量名。显然,有一天我有一个电话要接听或其他什么,并没有按照我的意愿完成案例陈述,但后来我确定我已经完成了。case 2 实际上应该在嵌套开关中,而不是作为原始外部开关的一部分(对于那些想知道的人,我在代码中使用命名常量,而不仅仅是幻数)。在 g++ 上,在没有任何选项的情况下编译时我没有收到警告或错误。

我的问题:为什么允许跨范围的情况下从开关跳转?它的用途是什么?

4

5 回答 5

4

Duff's Device 几乎不是已经建议的跨范围案例标签的“目的”,它只是对它的利用。

事实可能是它没有故意设计的目的,而仅仅是最简单可行的实现的产物。这样的设计使得 switch-case 结构可以做合理的事情,但也不能明确地保护你免受不合理的事情的影响。

于 2010-11-03T19:09:11.543 回答
4

案例标签只是标签,是(编译器生成的)goto 的目的地。

与普通标签具有功能范围一样,案例标签也具有switch范围。

唯一合理的优势是Duff 的 Device,但是它在现代计算机上并不是很相关。

所以,这是历史性的。

一个“冻结历史”的案例。

干杯&hth.,

于 2010-11-03T18:58:56.177 回答
1

switch 语句中的跨范围 case 标签确实有其用途,尤其是在实时、嵌入式系统应用程序中。一方面,它们允许更简洁的couroutines实现。它们还减少或消除了在类似的低级应用程序中使用 goto 语句。是的,goto 很丑,但是如果您在时间和同步问题成为常态之前编写了设备驱动程序,那么您会欣赏跨范围案例标签的用处,而不是 goto 语句的高度维护。如果你愿意,两害相权取其轻。

于 2013-02-25T20:40:17.747 回答
1

该代码仅出于历史原因编译。

请注意,它可能会导致非常奇怪的Undefined Behavior版本:

// don't try this at home
switch(x) {
  case 1:
  {
    std::string s = "hi!"
    case 2:
    cout << s; // doh!
  }
}

如果x==2, this 将s在不首先调用其构造函数的情况下访问。不过,我希望编译器会对此发出警告。

于 2010-11-03T19:10:03.380 回答
-1

您上面的代码是以下的同义词:

switch (x)
{
     case 1:
     case 2:
     cout << "hi";
}

编译器不会根据 switch-case 功能区分此代码和您发布的代码。它将其解释为指令的多个案例场景。

于 2010-11-03T19:00:56.617 回答