在C开关/ case中声明变量

时间:2010-11-25 14:34:44

标签: c++ c variables local switch-statement

嗯,这实际上不是一个问题..

我偶尔发现有一种有趣的方法可以在switch / case块中声明局部变量。您可以编写:

,而不是在每个案例块中使用大括号
switch (action) {
  int res;
  int value;
case ACTION_OPEN:
  res = open(...);
  ...
  break;
case  ...
}

所以,我只是想知道除了gcc之外还有哪些C / C ++编译器支持这种结构?它看起来像是一种常见的堕落。欢迎任何关于这种结构的评论!

4 个答案:

答案 0 :(得分:3)

switch body只是一个普通语句(在你的例子中是一个复合语句,看起来像{ ... }),它可以包含任何废话。包括案例标签。

这种转换哲学被Duffs device滥用。

许多人都没有意识到即使像switch(0) ;这样的东西也是一个有效的陈述(而不是有一个复合语句,它有一个空语句作为正文),虽然很无用。

答案 1 :(得分:1)

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

请注意,switch后面的内容几乎是一个正常的陈述,除了案例标签的可能性:

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

    return 0;
}

所以在ANSI C89中,这就是在这里发挥作用的大括号。

答案 2 :(得分:0)

严格来说,您使用int提供的案例在所有三种语言中均可使用,但原因各有不同。

C允许在所有情况下(对于C89)跳过任何局部变量(算术,structunion,数组...)的定义,并且在所有情况下都跳过一个(对于C99) 。 C99的例外是可变长度数组。

C ++仅允许这种情况用于没有构造函数或析构函数的数据类型,通常称为POD。

因此,如果您在C89的示例中有一个类型T而不是int,那么它总是有效的,而在C99和C ++中,它取决于类型T是否有效是对的。

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

答案 3 :(得分:-1)

我认为C99允许在块内部的任何地方声明变量(几乎),因此这种行为应该被认为是合法的......我没有看到任何实际风险,因为它只是一个声明。