【问题标题】:Why is declaring a variable in switch statement allowed? but not declaration + initialization?为什么允许在 switch 语句中声明变量?但不是声明+初始化?
【发布时间】:2019-05-23 03:43:43
【问题描述】:
  1. 为什么不允许在 switch 语句的情况下声明 + 初始化变量并给出错误,但如果在一行上声明它然后在另一行上赋值,它会编译?
  2. 为什么即使前面的 case 语句没有执行,也可以在另一个匹配的 case 中使用(操作)在前面的 case 中声明的变量!

此代码编译时没有错误或警告:

char ch; cin>> ch;
switch(ch)
{
    case 'a':
        int x;  // How come this is ok but not this(int x = 4;)?
        x = 4;
        cout<< x << endl;
        break;
    case 'b':
        x += 1;  // x is in scope but its declaration did not execute!
        cout<< x << endl;
        break;
    case 'c': 
        x += 1;
        cout<< x << endl;
        break;
}

我预计 case 'b'case 'c' 不知道有一个名为 x 的变量。我知道在案例 b 和案例 c 中该变量仍在范围内。

case 'a' 打印 4

case 'b' 打印 1

case 'c' 打印 1

编辑:没有其他标记为可能重复的问题线程不能回答我的问题。

  1. 为什么不能定义和初始化变量x?不允许这样做会造成什么问题?

如果只允许在一个语句中定义变量,那么在匹配的情况下使用该变量,并且使用其中的任何垃圾;那么和声明+初始化值有什么区别呢?

【问题讨论】:

  • 您为什么将您的问题同时标记为 C 和 C++?它们是非常不同的语言,即使没有 cout 的东西,它也不能编译为 C。注释的第一行是 C 中的约束违规。
  • 不允许单独在 switch 中声明,但在 switch 中创建的单独范围内声明在 C 中是可以的。 switch(ch) { case 'a': { int x; .. } case 'b' : ... }
  • @R..:我认为这是 C 语言中的语法错误。由于 int x; 是声明而不是语句,case 'a': ... 不满足标记语句的语法。 (但可以通过在case 'a': 之后添加分号来使其合法。)
  • @topcat 实际上是这样(虽然不是第一个):stackoverflow.com/a/19830820/1753435

标签: c++ switch-statement


【解决方案1】:

case 标签用作goto 语句的目标。

[stmt.dcl]/3 中的 C++ 标准状态:

可以转移到块中,但不能绕过初始化声明

所以下面会失败:

case 'a':
    int x = 4; //will fail

而以下不会失败:

case 'a':
    int x;  // this is ok 
    x = 4;

响应 OP 的编辑:

在这种特殊情况下,只有声明使x 在整个switch 语句中可见,因为它周围没有大括号{}。 所以x 也可以与其他cases 一起使用,尽管编译器会警告在未初始化的情况下使用它。请注意,读取 uninitialized variable 是未定义的行为。

回答你问题的最后一部分:
假设允许带有初始化的声明,这意味着x(在本例中为4)的特定值也必须在其他cases 中使用。 然后看起来好像执行了多个案例的代码。所以这是不允许的。

【讨论】:

  • 初始化是在运行时还是编译时完成?
  • @topcat 运行时。如果您有一个具有构造函数的类(如std::string x;),您将遇到同样的问题,因为构造函数将执行初始化。
  • @topcat:更新了帖子以响应您的编辑。
猜你喜欢
  • 2021-11-24
  • 2015-02-20
  • 1970-01-01
  • 2020-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多