代码之家  ›  专栏  ›  技术社区  ›  zserge

在C开关/case中声明变量

  •  7
  • zserge  · 技术社区  · 14 年前

    好吧,这实际上不是一个问题。

    我只是偶尔发现有一种有趣的方法可以在switch/case块中声明局部变量。不必在每个case块中使用大括号,您可以编写:

    switch (action) {
      int res;
      int value;
    case ACTION_OPEN:
      res = open(...);
      ...
      break;
    case  ...
    }
    

    所以,我只是想知道除了GCC之外的C/C++编译器支持这个结构吗?这看起来像是一个常见的失败。欢迎对本工程的任何意见!

    4 回复  |  直到 11 年前
        1
  •  1
  •   Fred Foo    14 年前

    符合C或C++编译器的任何标准都允许这样做。即使是老式的(iso c99之前的)C编译器也会允许这样做,但这仅仅是因为变量声明位于块/复合语句的开头(由 {} )

    注意下面的 switch 几乎是一个正常的声明,除了可能的大小写标签:

    int main(int argc, char* argv[])
    {
        switch (argc)
          default:
            puts("Hello, world!");
    
        return 0;
    }
    

    所以在ANSIC89中,正是大括号起了作用。

        2
  •  3
  •   Johannes Schaub - litb    14 年前

    开关主体只是一个普通语句(在您的例子中是一个复合语句,看起来像 { ... } )它可以包含任何垃圾。包括箱子标签。

    这种转换理念被滥用 Duffs device .

    很多人都不知道 switch(0) ; 是一个有效的语句(不是有一个复合语句,而是有一个空语句作为主体),尽管非常无用。

        3
  •  0
  •   Jens Gustedt    14 年前

    严格地说,你提出的案件 int 三种语言都允许,但原因不同。

    C允许跨越任何局部变量的定义(算术, struct , union ,array…)在所有情况下(对于C89)和所有情况下,除了一个(对于C99)。C99的例外是可变长度数组。

    C++只允许那些没有构造函数或析构函数的数据类型,通常称为POD。

    所以如果你有一个类型 T 而不是 int 在C89中的示例中,这总是有效的,在C99和C++中,它取决于类型。 T 是否正确。

    在任何情况下,所有这些都很容易导致未初始化的变量,所以最好不要这样做,如果您可以避免它。

        4
  •  -1
  •   Jack    14 年前

    我认为C99允许在块内任意位置声明变量(几乎),这样行为就应该被认为是合法的。我看不出任何实际的风险,因为这只是一个声明。