【问题标题】:C++11 is not executing switch correctly when variable is declared in case block在 case 块中声明变量时,C++11 未正确执行 switch
【发布时间】:2021-12-13 12:24:11
【问题描述】:

考虑下面的 sn-p。如果我用 GCC/C++11 编译它,那么我希望如果我用例如调用它var=2 该块已执行。无论如何,我希望至少调用 3 个 switch 块中的一个。

但是我得到的只是“开始”和“结束”行。 所以这个开关块不起作用:甚至没有调用“默认”。当我看到这个时我什至不相信 GDB!

其根本原因是案例块 1 (int anotherVar) 中的变量声明。为了解决这个问题,我需要在案例 1(自己的范围)周围添加括号,或者在顶部的构造函数主体中声明变量。

我的问题是:

  • 为什么会这样?技术原因是什么?如果不是在所有情况下都发生这种情况,那么在哪些情况下会发生这种情况?
  • 是否有编译器错误/警告标志?
MyClass::MyClass(int var) { 
   std::cout << "Constructor start" << std::endl;
   switch (var) {
     case 1:
       std::cout << "Case 1 executed" << std::endl;
       int anotherVar = doSomething();
     case 2:
       std::cout << "Case 2 executed" <<std::endl;
     break;
     default:
       std:cout << "Default executed" << std::endl;
   }
   std::cout << "Constructor ended" << std::endl;
}`

使用var=2 调用时会输出:

Constructor start
Constructor ended

【问题讨论】:

  • 能否请您发布所有代码
  • 最新的 g++ 不会按原样编译您的代码,因此它比警告要好。较旧的 g++ 似乎需要 -fpermissive 来编译此代码。
  • switch case大多只是标签(goto使用的),变量的定义和使用对goto/label有一定的限制(int anotherVar范围不限于@987654330 @)。
  • 只是提示:更改行 std::cout

标签: c++ c++11 gcc


【解决方案1】:

此示例格式不正确,使用符合要求的编译器会产生错误。

[stmt.dcl]/3 可以转移到块中,但不能通过初始化绕过声明的方式。一个程序从具有自动存储持续时间的变量不在范围内的点跳转到它在范围内的点的程序 (91) 是格式错误的,除非该变量具有标量类型、具有平凡默认构造函数的类类型和平凡析构函数,这些类型之一的 cv 限定版本,或上述类型之一的数组,并且在没有初始化程序的情况下声明 (11.6)。

脚注 91:从switch 语句的条件到case 标签的转移在这方面被认为是一个跳跃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    • 2017-02-03
    • 2020-12-27
    • 2012-07-13
    • 1970-01-01
    • 2015-08-02
    相关资源
    最近更新 更多