为什么如果(0),switch(0)不会产生警告?

时间:2015-12-01 15:21:20

标签: c visual-studio-2012 gcc clang

鉴于此代码:

#include <stdio.h>

int main( int argc, char** argv )
{
    switch (0) { 
        case 1: printf("1"); 
        case 2: printf("2"); 
        default:
            printf("default");
            break; 
    }
    return 0;
}

我希望编译器能告诉我一些关于条件表达式是否为常量switch (0)而VS2012为if(0)发出此警告)或< em>无法访问的代码(case 1case 2)。

但是,ideone和Visual Studio 2012以及最近的海湾合作委员会都没有收到类似的内容。

为什么甚至不好的编译器都会在这里抱怨?

4 个答案:

答案 0 :(得分:4)

我刚刚在CLANG上尝试了启用延长警告并收到以下警告:

enter image description here

简单地说(奇怪的是)只有交换机中两条线中的第一条永远不会被执行:

   case 1: printf("1"); 

答案 1 :(得分:3)

来自C 2011 standard

5.1.1.3诊断

1符合要求的实施应至少产生一条诊断信息(在 如果是预处理翻译单元或翻译单元,则是实现定义的方式 包含违反任何语法规则或约束的行为,即使行为也是明确的 指定为未定义或实现定义。 不需要诊断消息 在其他情况下产生。 9) 9)意图是实施应确定每种实施的性质,并在可能的情况下进行本地化 违反。当然,只要a,实现就可以自由地产生任意数量的诊断 有效的程序仍然正确翻译。它也可能成功翻译无效程序。

重点补充。

因此,如果在switchif控制表达式中使用常量表达式是违反约束,则需要进行诊断...

6.8.4.1 if声明

约束

1 if语句的控制表达式应具有标量类型 ...
6.8.4.2 switch声明

约束

1 switch语句的控制表达式应为整数类型。

2如果switch语句在范围内有关联的casedefault标签 具有可变修改类型的标识符,整个switch语句应在 该标识符的范围。 154)

3每个case标签的表达式应为整数常量表达式,而不是两个 同一switch语句中的大小写常量表达式应具有相同的值 转换后。 switch语句中最多可以有一个default标签。 (任何随附的switch语句可以包含default标签或case常量 具有在封闭中复制case常量表达式的值的表达式 switch声明。) 154)也就是说,声明要么在switch语句之前,要么在最后case之后 default标签与包含声明的块中的switch相关联。

......它不是。

这基本上是一个执行质量问题;实现可以发出诊断,以便在ifswitch语句中使用常量表达式,但它不必。 if( 0 )switch( 0 )可能会让我们大多数人感到羞耻,但不需要实施任何诊断。

答案 2 :(得分:1)

我刚试过clang -Weverything:它抱怨argcargv未被使用,但对switch(0)保持沉默,就像gcc一样。

虽然编译器不必强制发出诊断,但如果错误是拼写错误,警告可能会有所帮助。试试这个例子:

int test(int l) {
    switch (1) {
    case 0: return 0;
    case 1: return 1;
    default: return -1;
}

您应该在两个项目中提交错误。

编辑:clang似乎最近解决了这个问题,不像ryyker在回复中所说的那样,-Wunreachable-code并没有在我的笔记本电脑上抱怨。我可能有一个旧版本。

答案 3 :(得分:1)

要在Visual Studio 2013中获取警告,您需要:

  1. 右键点击该项目 - &gt;特性
  2. C / C ++中的常规设置警告级别为ALL
  3. 警告仅适用于if语句,因为该开关是一个块。

    enter image description here