为什么 gcc 会抛出一个隐含的 fallthrough 警告?

Why does gcc throw an implicit-fallthrough warning?

给定代码:

#include <stdlib.h> 

enum one {
    A, B
};

enum two {
    AA
};

int main(int argc, char *argv[])
{
    enum one one = atoi(argv[1]);
    enum two two = atoi(argv[2]);
    
    if ((one != A && one != B) || two != AA)
        return 1;
    
    switch (one) {
    case A:
        switch (two) {
        case AA:
            return 2;
        }
    case B:
        return 3;
    }
    return 0;
}

当我使用 gcc -Wimplicit-fallthrough test_fallthrough.c 编译它时,我收到以下警告

test_fallthrough.c: In function 'main':
test_fallthrough.c:21:3: warning: this statement may fall through [-Wimplicit-fallthrough=]
   21 |   switch (two) {
      |   ^~~~~~
test_fallthrough.c:25:2: note: here
   25 |  case B:
      |  ^~~~

它试图警告什么?我该怎么做才能不发出警告(我宁愿避免添加评论,例如 /* Falls through. */

通常,编译器会在每个 case 主体之后检查 break 语句,以确保程序流(fallthrough)没有错误。

在您的情况下,case A 正文没有 break,当 switch 语句与 case A.

switch (one) {
    case A:
        switch (two) {
        case AA:
            return 2;
        }
         // <------ no break here, flow will continue, or fall-through to next case body
    case B:
        return 3;
    }
    return 0;
}

您在第一个 switch 语句中缺少 break,它可能会跳转到第二种情况,它可以执行 case A 和之后的 Case B,因此出现警告。

//...
switch (one)
{
case A:
    switch (two)
    {
    case AA:
        return 2;
    }
    break; //breaking case A removes the warning.
case B:
    return 3;
}
//...

旁注:

  • 使用 argc 检查 argv[1]argv[2] 是否存在总是一个好主意。

Why does gcc throw an implicit-fallthrough warning?

嗯,因为它可能会失败。

What is it trying to warn against

two != AA.

case A 跌落到 case B

what can I do so that it does not warn

在低于 7 的 gcc 上使用注释,即。 one of the markers that disable the warning:

/* falls through */

在 gcc 7 以上你可以 use a attribute:

__attribute__((__fallthrough__));

在 gcc 10 以上你可以使用 the attribute from C2x:

[[fallthrough]];

--

请注意,if (one != A || one != B || two != AA) 并没有真正检查任何内容,因为 one != A || one != B 始终为真。我猜你的意思是 if ((one != A && one != B) || two != AA)-Wimplicit-falthrough= 警告仍然没有考虑到 if