c++ switch语句中的猫腻

来源:互联网 发布:sql server 2005下载 编辑:程序博客网 时间:2024/04/28 10:57
发信人: Arnald (堕落兽人), 信区: CPlusPlus
标  题: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 12:28:08 2005), 站内

我用gcc编译器
下面的代码编译不过

#include <stdio.h>

int main()
{
  int i;
  switch (i)
  {
    case 3:
      int y = 0;
      break;
    default:
      break;
  }
}

出错提示
main.cpp: In function `int main()':
main.cpp:11: jump to case label
main.cpp:9:   crosses initialization of `int y'

但是把case里面用{}括起来,或者改成“ int y; y = 0;”,就可以编译过
以前都没有注意到C++还哟这个限制
不明白为什么C++会有这样的语法限制呢???
望指教


--
金钱不能解决一切,但是可以解决我;暴力不能解决一切,但是可以解决你


※ 来源:·水木社区 http://newsmth.net·[FROM: 219.142.125.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:coolest] [进入讨论区] [返回顶部] 2 发信人: coolest (舍利子~~~怪兽一朵朵), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 12:34:02 2005), 站内

首先default需要break吗?我怎么记得不用的
二来,int y在这里没有任何用处,出了switch也就出了域,可能就是因为这个原因
你修改了以后, y=0这句就用上了
【 在 Arnald (堕落兽人) 的大作中提到: 】
: 我用gcc编译器
: 下面的代码编译不过
: #include <stdio.h>
: ...................

--
               我是清都山水郎  天教懒慢带疏狂
                     曾批给露支风敕  累奏留云借月章
                          诗万首  酒千觞  几曾着眼看侯王
                                  玉楼金阙慵归去  且插梅花醉洛阳


※ 来源:·水木社区 newsmth.net·[FROM: 211.156.222.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:RoachCock] [进入讨论区] [返回顶部] 3 发信人: RoachCock (火并科尔,谁没腰肌?), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 12:36:56 2005), 站内

一个块内的变量初始化不能条件性的跳过

【 在 Arnald (堕落兽人) 的大作中提到: 】
: 我用gcc编译器
: 下面的代码编译不过
: #include <stdio.h>
: ...................

--
那些在刑场上争先恐后吃袁督师肉的人,在北京两次沦陷的时候有几个挺身而出的?


※ 来源:·水木社区 newsmth.net·[FROM: 218.2.150.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:eastcrusader] [进入讨论区] [返回顶部] 4 发信人: eastcrusader (昨我已逝), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 12:54:26 2005), 站内

有这种限制,如果你定义一个变量,并且在后面还要使用它, 那么它的
定义部分不能被条件跳过。比如你不能这样:
if(flag==true)
  int j=0;

if(j==0)
  ....

将会给出j没有定义之类的错误。
【 在 Arnald (堕落兽人) 的大作中提到: 】
: 我用gcc编译器
: 下面的代码编译不过
: #include <stdio.h>
: ...................

--

※ 来源:·水木社区 newsmth.net·[FROM: 221.218.19.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:cloudd] [进入讨论区] [返回顶部] 5 发信人: cloudd (流氓理想主义者), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 12:57:00 2005), 站内

为什么他加了花括号以后又可以通过了呢?

【 在 RoachCock (火并科尔,谁没腰肌?) 的大作中提到: 】
: 一个块内的变量初始化不能条件性的跳过


--
流氓也要攒rp


※ 来源:·水木社区 newsmth.net·[FROM: 61.173.81.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:Arnald] [进入讨论区] [返回顶部] 6 发信人: Arnald (堕落兽人), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 12:59:23 2005), 站内

只是讨论语法问题

如果想你说的,也只应该是warning,而不是error

【 在 coolest (舍利子~~~怪兽一朵朵) 的大作中提到: 】
: 首先default需要break吗?我怎么记得不用的
: 二来,int y在这里没有任何用处,出了switch也就出了域,可能就是因为这个原因
: 你修改了以后, y=0这句就用上了



--
金钱不能解决一切,但是可以解决我;暴力不能解决一切,但是可以解决你


※ 来源:·水木社区 http://newsmth.net·[FROM: 219.142.125.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:Arnald] [进入讨论区] [返回顶部] 7 发信人: Arnald (堕落兽人), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 13:01:13 2005), 站内

能不能详细的解释一下

为什么这样又能编译的过?
  switch (value)
  {
    case 1:
      int y;
      y = 1;
  }




【 在 RoachCock (火并科尔,谁没腰肌?) 的大作中提到: 】
: 一个块内的变量初始化不能条件性的跳过



--
我在改code的时候总在想,我底是在refactor,还是在hack。


※ 来源:·水木社区 http://newsmth.net·[FROM: 219.142.125.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:jijiliang] [进入讨论区] [返回顶部] 8 发信人: jijiliang (克己复礼), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 13:10:02 2005), 站内

因为括号外面没有y了。。。
【 在 Arnald (堕落兽人) 的大作中提到: 】
: 能不能详细的解释一下
: 为什么这样又能编译的过?
:   switch (value)
: ...................

--

※ 来源:·水木社区 newsmth.net·[FROM: 59.66.114.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:twingle] [进入讨论区] [返回顶部] 9 发信人: twingle (打断了第四根线), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 13:10:10 2005), 站内

加了花括号就生成了一个新的block,当然可以通过了

【 在 cloudd (流氓理想主义者) 的大作中提到: 】
: 为什么他加了花括号以后又可以通过了呢?


--

※ 来源:·水木社区 newsmth.net·[FROM: 219.142.59.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:qbasic] [进入讨论区] [返回顶部] 10 发信人: qbasic (没有), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 13:10:25 2005), 站内

木有跳过呀
没default了就没有跳过嘛
你多几个case试试就知道了
【 在 Arnald (堕落兽人) 的大作中提到: 】
: 能不能详细的解释一下
: 为什么这样又能编译的过?
:   switch (value)
: ...................

--
一沙一世界
            一树一菩提。


※ 来源:·水木社区 newsmth.net·[FROM: 162.105.242.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:Arnald] [进入讨论区] [返回顶部] 11 发信人: Arnald (堕落兽人), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 13:13:53 2005), 站内

什么没有跳过?

下面的代码在int z = 0上编译错误
  switch (value)
  {
    case 1:
      int y;
      y = 1;   // compile ok
      break;
    case 2:
      int z = 0; // compile error
      break;
    default:
      break;
  }


【 在 qbasic (没有) 的大作中提到: 】
: 木有跳过呀
: 没default了就没有跳过嘛
: 你多几个case试试就知道了



--
“我是有老婆的男人,不要和我说ppmm,不然回去会跪挫衣板的。”
                     ——老婆让我使用的签名档


※ 来源:·水木社区 http://newsmth.net·[FROM: 219.142.125.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:eastcrusader] [进入讨论区] [返回顶部] 12 发信人: eastcrusader (昨我已逝), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 13:16:06 2005), 站内

这个问题的解释如下,如果你在一个swith语句中,
如果有如下情况出现:
switch(flag){
  case flag1:
     int a;
     break;
  case flag2;
     ....
     break;
}

那么flag1 中的定义 int a,在flag2的语句中是可以
直接访问的,这时候,不管你在flag2的语句中是否存
在访问a的语句,他都认为a的这种定义非法(因为它认
为你有在其他flag中访问变量a的可能),等价于我
前面提到的这种情况:
  if(flag)
      int a=0;
  if(a==0)
     ...
但是,如果你用{},这时flag1的内容就是一个语句块
,明确的告诉编译器,a的定义在其他的flag中是不可
见的,这时就是合法语句。

功力不够,不知道自己说明白了没有。

【 在 Arnald (堕落兽人) 的大作中提到: 】
: 能不能详细的解释一下
: 为什么这样又能编译的过?
:   switch (value)
: ...................

--

※ 修改:·eastcrusader 于 Jul 22 13:31:29 修改本文·[FROM: 221.218.19.*]
※ 来源:·水木社区 newsmth.net·[FROM: 221.218.19.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:Arnald] [进入讨论区] [返回顶部] 13 发信人: Arnald (堕落兽人), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 13:36:35 2005), 站内

谢谢解释
这可以解释为什么加了{}就可以编译过,但是为什么下面的也能编译过呢?


switch(flag){
  case flag1:
     int a;
     a = 1;

     break;
  case flag2;
     ....
     break;
}
【 在 eastcrusader (昨我已逝) 的大作中提到: 】
: 这个问题的解释如下,如果你在一个swith语句中,
: 如果有如下情况出现:
: switch(flag){
: ...................



--
金钱不能解决一切,但是可以解决我;暴力不能解决一切,但是可以解决你


※ 来源:·水木社区 http://newsmth.net·[FROM: 219.142.125.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:eastcrusader] [进入讨论区] [返回顶部] 14 发信人: eastcrusader (昨我已逝), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 13:44:41 2005), 站内

此时,编译器认为int i;是一个declaration(声明),而不是一个定义(definition),
这个时候编译器显得比较弱智,你看如下语句很荒谬,但是可以通过:
   switch(tag) {
    case 1 :
      int y;
      y=0;
      break;
    default:
      y=100;
   }
但是这样按照我们的逻辑是不对的,觉得编译器发现不了,呵呵。如果你写
   int i=0;
那么它就是一个定义了,呵呵,编译器就发现了错误。

其实这个语句与下面的语句等价理解,错是没有错的,但是和大家认为的逻辑不同,
特别在编译器内部的逻辑认为是和这个等价的:
   switch(i) {
    int y;
    case 1 :
      y=0;
      break;
    default:
      y=100;
      break;
}
【 在 Arnald (堕落兽人) 的大作中提到: 】
: 谢谢解释
: 这可以解释为什么加了{}就可以编译过,但是为什么下面的也能编译过呢?
: switch(flag){
: ...................

--

※ 修改:·eastcrusader 于 Jul 22 13:49:13 修改本文·[FROM: 221.218.19.*]
※ 来源:·水木社区 newsmth.net·[FROM: 221.218.19.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:Arnald] [进入讨论区] [返回顶部] 15 发信人: Arnald (堕落兽人), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 13:52:07 2005), 站内

明白了
谢谢

【 在 eastcrusader (昨我已逝) 的大作中提到: 】
: 此时,编译器认为int i;是一个declaration(声明),而不是一个定义(definition),
: 这个时候编译器显得比较弱智,你看如下语句很荒谬,但是可以通过:
:    switch(tag) {
: ...................



--
#include <stdio.h>
int main(){char *p="#include <stdio.h>%cint main(){char *p=%c%s%c; printf(p, 10, 34, p, 34, 10);}%c"; printf(p, 10, 34, p, 34, 10);}


※ 来源:·水木社区 http://newsmth.net·[FROM: 219.142.125.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:jasss] [进入讨论区] [返回顶部] 16 发信人: jasss (robot), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 14:02:42 2005), 站内


【 在 eastcrusader (昨我已逝) 的大作中提到: 】
: 此时,编译器认为int i;是一个declaration(声明),而不是一个定义(definition),

This is not correct, in C++  

    int i;

is a perfect definition, not a declaration in c++, 
and please note C++ does not have tentative definition...

: 这个时候编译器显得比较弱智,你看如下语句很荒谬,但是可以通过:
:    switch(tag) {
:     case 1 :
:       int y;
:       y=0;

Here 
    int y;
is a definition, and 

    y=0;

is a *assignment*, not a *initialization* ...

:       break;
:     default:
:       y=100;
:    }
: 但是这样是不对的,编译器它发现不了,呵呵。如果你写
:    int i=0;

However, 

    int i=0;

is a definition with *initialization*...

: 那么它就是一个定义了,呵呵,编译器就发现了错误。

Actually write 
    int i=0;
within the switch-case is not an error, the problem
is you can not skip it ...


--

※ 来源:·水木社区 http://newsmth.net·[FROM: 192.51.44.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:ilovecpp] [进入讨论区] [返回顶部] 17 发信人: ilovecpp (cpp), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 14:14:16 2005), 站内

This seems to be a FAQ.  Could you contribute one?

【 在 jasss (robot) 的大作中提到: 】
: This is not correct, in C++  
:     int i;
: is a perfect definition, not a declaration in c++, 
: ...................

--

※ 来源:·水木社区 newsmth.net·[FROM: 218.249.22.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:jasss] [进入讨论区] [返回顶部] 18 发信人: jasss (robot), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 14:22:48 2005), 站内


【 在 Arnald (堕落兽人) 的大作中提到: 】
: 谢谢解释
: 这可以解释为什么加了{}就可以编译过,但是为什么下面的也能编译过呢?

To explain the rationale, I changed your code to :

switch(flag){
  case flag1:
     int a;       // here no initialization for a
     a = 1;       // this assignment is irrelative
     break;
  case flag2:
     int b = 1;   // Note here we have initialization for b
     break;
  default:   
     // and we still in the same scope here
     // 
     break;

}

Here, for
    int a;
the compiler does not care about its actual content, since 
you did not initialize it. Garbage is ok...

However, for 
    int b = 1;
the compiler knows Arnald needs a integer b with 1 as its 
initial value. And it also found it is possible that in default 
region, the b can be used. Since the compiler cannot make sure 
the b will be initialized correctly for every flag, then it just 
issue an error(warning for some other compilers), and hope you 
can handle it...

And if you remove the default part, the error will dispear, 
since there is no initialization *skip* now... 

Just put them in the case scope if you really want it... 
--

※ 来源:·水木社区 http://newsmth.net·[FROM: 192.51.44.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:qbasic] [进入讨论区] [返回顶部] 19 发信人: qbasic (没有), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 14:29:33 2005), 站内

nod

如果吧上面的弄到下面去,即使没有default 一个好点的编译器也会大声抱怨


【 在 jasss (robot) 的大作中提到: 】
: 标  题: Re: C++对switch-case的语法有这样的要求吗?
: 发信站: 水木社区 (Fri Jul 22 14:22:48 2005), 站内


: 【 在 Arnald (堕落兽人) 的大作中提到: 】
: : 谢谢解释
: : 这可以解释为什么加了{}就可以编译过,但是为什么下面的也能编译过呢?

: To explain the rationale, I changed your code to :

: switch(flag){
:   case flag1:
:      int a;       // here no initialization for a
:      a = 1;       // this assignment is irrelative
:      break;
:   case flag2:
:      int b = 1;   // Note here we have initialization for b
:      break;
:   default:   
:      // and we still in the same scope here
:      // 
:      break;

: }

: Here, for
:     int a;
: the compiler does not care about its actual content, since 
: you did not initialize it. Garbage is ok...

: However, for 
:     int b = 1;
: the compiler knows Arnald needs a integer b with 1 as its 
: initial value. And it also found it is possible that in default 
: region, the b can be used. Since the compiler cannot make sure 
: the b will be initialized correctly for every flag, then it just 
: issue an error(warning for some other compilers), and hope you 
: can handle it...

: And if you remove the default part, the error will dispear, 
: since there is no initialization *skip* now... 

: Just put them in the case scope if you really want it... 
: --

: ※ 来源:·水木社区 http://newsmth.net·[FROM: 192.51.44.*]


--
一沙一世界
            一树一菩提。


※ 来源:·水木社区 newsmth.net·[FROM: 162.105.242.*]

  [本篇全文] [回复文章] [回信给作者] [本篇作者:eastcrusader] [进入讨论区] [返回顶部] 20 发信人: eastcrusader (昨我已逝), 信区: CPlusPlus
标  题: Re: C++对switch-case的语法有这样的要求吗?
发信站: 水木社区 (Fri Jul 22 14:30:44 2005), 站内

yes, you are right, in c++ syntax, 
definition i=0; //initialized
definition i;   //uninitialized

all are valid. they are all definition. all
the compiling time errors come from the  difference 
of initialized or not, which is the one of the essential
diff from the C language. I think here should be 
something to distinguish the 2 kinds of definition,
at least in chinese.
   I think this involves the "ideology" of C++ and
C, about the initialization. here are lots of syntax
problems aout initialization. 
   we welcome your idea about this,:).
【 在 jasss (robot) 的大作中提到: 】
: This is not correct, in C++  
:     int i;
: is a perfect definition, not a declaration in c++, 
: ...................

--