嗯,这实际上不是一个问题..
我偶尔发现有一种有趣的方法可以在switch / case块中声明局部变量。您可以编写:
,而不是在每个案例块中使用大括号switch (action) {
int res;
int value;
case ACTION_OPEN:
res = open(...);
...
break;
case ...
}
所以,我只是想知道除了gcc之外还有哪些C / C ++编译器支持这种结构?它看起来像是一种常见的堕落。欢迎任何关于这种结构的评论!
答案 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)跳过任何局部变量(算术,struct
,union
,数组...)的定义,并且在所有情况下都跳过一个(对于C99) 。 C99的例外是可变长度数组。
C ++仅允许这种情况用于没有构造函数或析构函数的数据类型,通常称为POD。
因此,如果您在C89的示例中有一个类型T
而不是int
,那么它总是有效的,而在C99和C ++中,它取决于类型T
是否有效是对的。
在任何情况下,所有这些都很容易导致未初始化的变量,所以如果你能避免它,最好不要这样做。
答案 3 :(得分:-1)
我认为C99允许在块内部的任何地方声明变量(几乎),因此这种行为应该被认为是合法的......我没有看到任何实际风险,因为它只是一个声明。