代码之家  ›  专栏  ›  技术社区  ›  San Jacinto

C++中的范围case语句:跨范围案例标签的目的?

  •  0
  • San Jacinto  · 技术社区  · 14 年前

    我的当前代码中有一个bug,我已经用头撞了几天了。我将发布下面代码的摘要版本(不是我的实际代码,但它仍然编译)。

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
      int x = 7;
    
      switch(x)
      {
        case 1:
        {
          case 2:
          cout << "hi";
        }
      }
    }
    

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

    我的问题是:为什么允许跨范围案例从开关跳出来?它有什么作用?

    5 回复  |  直到 14 年前
        1
  •  4
  •   Clifford    14 年前

    达夫的设备很难像前面提到的那样成为跨领域案例标签的“目的”,它只是对它的一种利用。

    事实可能是它不起作用 特意设计的 目的,但仅仅是一个最简单的可行实现的人工制品。这种设计使得switch-case构造可以精确地执行合理的操作,但也不能明确地保护您免受不合理的操作。

        2
  •  4
  •   Cheers and hth. - Alf    14 年前

    case标签只是标签,用于(编译器生成的)goto的目的地。

    与普通标签具有相同的功能范围,案例标签具有 switch 范围。

    唯一合理的优势是 Duff's Device 然而,这在现代计算机上并不十分重要。

    所以,这是历史性的。

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

    干杯!

        3
  •  1
  •   sbi    14 年前

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

    请注意,它可能会导致 未定义的行为 :

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

    如果 x==2 ,这将访问 s 不需要先调用它的构造函数。不过,我希望编译器对此发出警告。

        4
  •  1
  •   Luis Paris    11 年前

    switch语句中的跨范围大小写标签 为某个目的服务,特别是在实时、嵌入式系统应用程序中。首先,它们允许 couroutines . 它们还减少或消除了在类似的低级应用程序中使用goto语句。是的,goto很难看,但是如果你以前写过设备驱动程序,而时间和同步问题是规范的,那么你会很欣赏跨范围的case标签对于goto语句的高度维护的有用性。两害相权取其轻。

        5
  •  -1
  •   Ahrotahntee    14 年前

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

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

    编译器不区分此代码和您根据开关盒功能发布的代码。它将其解释为说明的多个案例场景。