提问人:asimes 提问时间:7/22/2015 最后编辑:asimes 更新时间:7/22/2015 访问量:1280
C 与 C++ 开关语句变量定义与声明
C vs C++ switch statement variable definition vs declaration
问:
我正在玩一些语法,发现了一些奇怪的编译器规则,想知道这样做的原因是什么
C 不会编译它,但 C++ 会:
switch (argc) {
case 0:
int foo;
break;
default:
break;
}
C 和 C++ 都将编译以下内容:
switch (argc) {
case 0:
; int foo;
break;
default:
break;
}
C 将编译这个,但不会编译 C++:
switch (argc) {
case 0:
; int foo = 0;
break;
default:
break;
}
gcc -v
是如果它很重要。我意识到解决方案是用大括号包裹内容,但我对编译错误的原因更感兴趣gcc version 4.9.3 (MacPorts gcc49 4.9.3_0)
case 0:
答:
23赞
sepp2k
7/22/2015
#1
case 0:
int foo;
在 C 和 C++ 中,带标签的语句都是后跟语句的标签。但是,在 C++ 中,语句的定义包括“块声明”(即可能出现在块中的声明和定义),而在 C 中则不包括(在 C 中,块是一系列“块项”,它们是块声明或语句 - 在 C++ 中,它是一系列语句,其中包括块声明)。
case 0:
; int foo;
这之所以有效,是因为在 C 和 C++ 中都是一个(n 空)语句,所以这里我们确实有一个标签后跟一个语句。;
case 0:
; int foo = 0;
正如注释中已经解释的那样,这在 C++ 中不起作用,因为 C++ 使跳过初始化成为非法的。
评论
0赞
asimes
7/22/2015
这是一个很好的答案,但第三种情况仍然是最让我困惑的情况。它是如何跳过初始化的?为什么将定义放在大括号内可以避免跳过初始化?
1赞
chris
7/22/2015
@asimes,当你加大括号时,是标记语句的语句。如果不这样做,则是开关的一部分,而不是案例的一个语句,因此它在下一个标签之外的范围内,但会跳过其初始化。{; int foo = 0;}
int foo = 0;
0赞
sepp2k
7/22/2015
@asimes 它可能会跳过初始化,因为它可能会跳转到默认情况,即在范围内但未初始化。如果添加大括号,则不再在默认块的范围内。基本上,“跳过初始化”规则禁止您跳过具有初始值设定项的变量范围的“中间”。也就是说,您可以跳转到初始化或变量超出范围后跳转到初始化,但不能跳转到这些点之间的任何位置。foo
foo
0赞
jaggedSpire
7/22/2015
如果可以的话:为什么分离 placate gcc 的声明和初始化,当初始化仍在 switch 语句中,并且至少被一种情况跳过时?foo
3赞
chris
7/22/2015
@jaggedSpire,分配不是初始化。您可以轻松地做到,而无需跳过任何内容。int i; foo(i); i = 0;
评论
foo